| Printable Version of Topic
Click here to view this topic in its original format |
| Unofficial VirtualDub Support Forums > VirtualDub Filters and Filter Development > Filter - Separate Rgb Arrays |
| Posted by: mancanfly Mar 26 2003, 02:58 AM |
| Hello, I am interested in developing a filter for Virtual Dub and would need some help from developers. Actually the filter has already been developed for images and I want to extend it to videos. The following is written in 'filtsdk-1_05\Filtsdk\docs\crashcourse.html' (the filter SDK provided on VirtualDub website)- "...This generally means that if you need to do any arithmetic on a pixel, such as averaging several together, you will need to either unpack the pixels into triplets to get more range or mask off bits to reduce precision. The latter generally leads to poor results, so you will want to unpack pixels." To begin with, I would like to do a simple operation (in the same format and not through masking) as: for(i=0;i<w;i++) //assign destination the modified RGBs. { for(j=0;j<h;j++) { dst[count++] = IpixelR[i][j]; dst[count++] = IpixelG[i][j]/2; dst[count++] = IpixelB[i][j]/3; } } and not as: do { w = fa->src.w; do { Pixel32 old_pixel, new_pixel; old_pixel = *src++; new_pixel = (old_pixel & 0xFF0000) + ((old_pixel & 0x00FF00)>>1) + 0x0000FF; *dst++ = new_pixel; } while(--w); src = (Pixel32 *)((char *)src + fa->src.modulo); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } while(--h); Can somebody suggest me the required changes in the example given in 'filtsdk-1_05\Filtsdk\docs\tutorial_maincode.html' to achieve this? waiting for a reply.[B][/B] |
| Posted by: fccHandler Mar 26 2003, 03:27 AM | ||
I don't really understand your question, but I think what the SDK is saying is that it's better to split the pixel into its R/G/B components and do the math on the components, rather than on the pixel as a whole:
Does this help you at all? |
| Posted by: mancanfly Mar 28 2003, 02:41 AM |
| actually what i am interested in is processing a 2D array (of the form PixelR[i][j], PixelG[i][j], PixelB[i][j]) of different pixels instead of handling individual RGBs (in a scanline). How can I store the RGB components of the frame in a 2D array? Consider the 2D array being created as follows: _______________________________________________ //Allocation of R,G,B components of Input Image begins... float **IpixelR, **IpixelG, **IpixelB; IpixelR = (float **)malloc((fa->src.w)*sizeof(float *)); IpixelG = (float **)malloc((fa->src.w)*sizeof(float *)); IpixelB = (float **)malloc((fa->src.w)*sizeof(float *)); for(j=0;j<(fa->src.h);j++) { IpixelR[j] = (float *)malloc((fa->src.w)*sizeof(float)); IpixelG[j] = (float *)malloc((fa->src.w)*sizeof(float)); IpixelB[j] = (float *)malloc((fa->src.w)*sizeof(float)); } _______________________________________________ And consider what you suggested in the following loop: h = fa->src.h; for (i=h; i>0; i--) { w = fa->src.w; for (j=w; j>0; j--) { Pixel32 old_pixel, new_pixel; old_pixel = *src++; int r,g,b, l; //Unpack red, green, and blue //IpixelR[j][i] = r = (old_pixel >> 16) & 0xFF; //IpixelG[j][i] = g = (old_pixel >> 8) & 0xFF; //IpixelB[j][i] = b = old_pixel & 0xFF; //Do some math with r, g, and b... g = g / 2; b = b / 3; //Clamp the results if necessary if (r < 0) r = 0; else if (r > 255) r = 255; if (g < 0) g = 0; else if (g > 255) g = 255; if (b < 0) b = 0; else if (b > 255) b = 255; //Pack into new pixel new_pixel = (r << 16) + (g << 8) + b; *dst++ = new_pixel; } src = (Pixel32 *)((char *)src + fa->src.modulo); dst = (Pixel32 *)((char *)dst + fa->dst.modulo); } thanks for you earlier reply! |
| Posted by: fccHandler Mar 28 2003, 03:38 AM | ||
I still don't completely understand, but it sounds like what you want is a planar image of floats, however, VirtualDub's internal storage is packed bytes. It's still possible to convert from one to the other for your processing, but it won't be terribly efficient:
I didn't test the code but it should work (if I haven't make any typos). Also, it's better to alloc/dealloc in StartProc/EndProc. |
| Posted by: mancanfly Mar 29 2003, 07:26 PM |
| This thing is really confusing me.. Now where is the mistake?? On debugging I get error in the line where comments are in UPPERCASE (where I assign the src values to IpixelR[i][j], IpixelG[i][j], IpixelB[i][j]. ________________________________________________________ int i,j, count; //Allocation of R,G,B components of Input Image begins... float **IpixelR, **IpixelG, **IpixelB; IpixelR = (float **)malloc((fa->src.h)*sizeof(float *)); IpixelG = (float **)malloc((fa->src.h)*sizeof(float *)); IpixelB = (float **)malloc((fa->src.h)*sizeof(float *)); for(j=0;j<(fa->src.h);j++) { IpixelR[j] = (float *)malloc((fa->src.w)*sizeof(float)); IpixelG[j] = (float *)malloc((fa->src.w)*sizeof(float)); IpixelB[j] = (float *)malloc((fa->src.w)*sizeof(float)); } // Convert source to planar format for (j = 0; j < fa->src.h; j++) { for (i = 0; i < fa->src.w; i++) { Pixel32 p = *src++; IpixelR[i][j] = (p >> 16) & 0xFF; //ERROR ON DEBUGGING IpixelG[i][j] = (p >> 8) & 0xFF; IpixelB[i][j] = p & 0xFF; } src = (Pixel32 *)((char)src + fa->src.modulo); } // Write to destination in packed format int r,g,b; for (j = 0; j < fa->src.h; j++) { for (i = 0; i < fa->src.w; i++) { r = (int)IpixelR[i][j]; g = (int)IpixelG[i][j]; b = (int)IpixelB[i][j]; if (r < 0) r = 0; else if (r > 255) r = 255; if (g < 0) g = 0; else if (g > 255) g = 255; if (b < 0) b = 0; else if (b > 255) b = 255; *dst++ = (Pixel32)((r << 16) + (g << 8) +b); } dst = (Pixel32 *)((char)dst + fa->dst.modulo); } // Deallocate arrays // ... _____________________________________ The error message says that: AVIAudioPreviewOutputStream: flushing... First-chance exception in VirtualDub.exe: 0xC0000005: Access Violation. |
| Posted by: phaeron Mar 29 2003, 08:42 PM |
| Your arrays are allocated [y][x] but you are accessing them [x][y]. |
| Posted by: fccHandler Mar 29 2003, 08:58 PM | ||||
| It should be:
Don't forget to deallocate:
|
| Posted by: mancanfly Mar 30 2003, 09:05 PM |
| Seems FOURCC is not with me! Can you just create a .cpp file (say, test_filter.cpp) and test the following code for me? Now the error line is the one where the src pointer is being equated to the Pixel32 variable 'p'. I truly appreciate your patience. Though it has to be something trivial, but this step has become so critical that I simply can't proceed with my work any further without it getting completed. Actually I intend to do some matrix operations on the frame array hence obtained. _____________________________________________ #include <stdio.h> #include "filter.h" #include "filters.h" #include "f_convolute.h" #include "ScriptInterpreter.h" #include "ScriptValue.h" #include "ScriptError.h" int tutorialRunProc(const FilterActivation *fa, const FilterFunctions *ff) { PixDim w, h; Pixel32 *src, *dst; src = (Pixel32 *)fa->src.data; dst = (Pixel32 *)fa->dst.data; int i,j, count; //Allocation of R,G,B components of Input Image begins... float **IpixelR, **IpixelG, **IpixelB; IpixelR = (float **)malloc((fa->src.w)*sizeof(float *)); IpixelG = (float **)malloc((fa->src.w)*sizeof(float *)); IpixelB = (float **)malloc((fa->src.w)*sizeof(float *)); for(j=0;j<(fa->src.w);j++) { IpixelR[j] = (float *)malloc((fa->src.h)*sizeof(float)); IpixelG[j] = (float *)malloc((fa->src.h)*sizeof(float)); IpixelB[j] = (float *)malloc((fa->src.h)*sizeof(float)); } /////////// // Convert source to planar format for (j = 0; j < fa->src.h; j++) { for (i = 0; i < fa->src.w; i++) { Pixel32 p = (Pixel32) *src++; // <-- ERROR ON DEBUGGING IpixelR[i][j] = (p >> 16) & 0xFF; IpixelG[i][j] = (p >> 8) & 0xFF; IpixelB[i][j] = p & 0xFF; } src = (Pixel32 *)((char)src + fa->src.modulo); } /////////// // // Do some stuff with the planar image // /////////// // Write to destination in packed format int r,g,b; for (j = 0; j < fa->src.h; j++) { for (i = 0; i < fa->src.w; i++) { r = (int)IpixelR[i][j]; g = (int)IpixelG[i][j]/2; b = (int)IpixelB[i][j]/3; if (r < 0) r = 0; else if (r > 255) r = 255; if (g < 0) g = 0; else if (g > 255) g = 255; if (b < 0) b = 0; else if (b > 255) b = 255; *dst++ = (Pixel32)((r << 16) + (g << 8) + b); } dst = (Pixel32 *)((char)dst + fa->dst.modulo); } //free allocated memory for(i=(fa->src.w)-1;i>=0;i--) { free(IpixelR[i]); free(IpixelG[i]); free(IpixelB[i]); } free(IpixelR); free(IpixelG); free(IpixelB); return 0; } struct FilterDefinition filterDef_tutorial = { NULL, NULL, NULL, // next, prev, module "tutorial", // name "This is a test filter.", // desc "test", // maker NULL, // private_data 0, // inst_data_size NULL, // initProc NULL, // deinitProc tutorialRunProc, // runProc NULL, // paramProc NULL, // configProc NULL, // stringProc NULL, // startProc NULL, // endProc NULL, // script_obj NULL, // fssProc }; _____________________________________________ |
| Posted by: phaeron Mar 30 2003, 09:53 PM |
| src = (Pixel32 *)((char)src + fa->src.modulo); That should be (char *). |
| Posted by: fccHandler Mar 31 2003, 05:50 AM |
| For sure, next time I will test any code before I post it. |