|
|
| mancanfly |
| Posted: Mar 26 2003, 02:58 AM |
 |
|
Unregistered

|
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] |
 |
| fccHandler |
| Posted: Mar 26 2003, 03:27 AM |
 |
|
Administrator n00b
  
Group: Moderators
Posts: 3961
Member No.: 280
Joined: 13-September 02

|
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:
| CODE | int r,g,b;
/* Unpack red, green, and blue */ r = (old_pixel >> 16) & 0xFF; g = (old_pixel >> 8) & 0xFF; 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; |
Does this help you at all?
-------------------- May the FOURCC be with you... |
 |
| mancanfly |
| Posted: Mar 28 2003, 02:41 AM |
 |
|
Unregistered

|
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! |
 |
| fccHandler |
| Posted: Mar 28 2003, 03:38 AM |
 |
|
Administrator n00b
  
Group: Moderators
Posts: 3961
Member No.: 280
Joined: 13-September 02

|
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:
| CODE | // Allocate your arrays // ...
// Convert source to planar format int i,j; Pixel32 *src = fa->src.data; 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; 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; Pixel32 *dst = fa->dst.data; for (j = 0; j < fa->dst.h; j++) { for (i = 0; i < fa->dst.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 your arrays // ...
|
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.
-------------------- May the FOURCC be with you... |
 |
| mancanfly |
| Posted: Mar 29 2003, 07:26 PM |
 |
|
Unregistered

|
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. |
 |
| phaeron |
| Posted: Mar 29 2003, 08:42 PM |
 |
|

Virtualdub Developer
  
Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02

|
Your arrays are allocated [y][x] but you are accessing them [x][y]. |
 |
| fccHandler |
| Posted: Mar 29 2003, 08:58 PM |
 |
|
Administrator n00b
  
Group: Moderators
Posts: 3961
Member No.: 280
Joined: 13-September 02

|
Doh! I didn't look closely enough at your allocation strategy, sorry. (Thanks phaeron!)
It should be:
| CODE | //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(i=0;i<(fa->src.w);i++) { IpixelR[i] = (float *)malloc((fa->src.h)*sizeof(float)); IpixelG[i] = (float *)malloc((fa->src.h)*sizeof(float)); IpixelB[i] = (float *)malloc((fa->src.h)*sizeof(float)); } |
Don't forget to deallocate:
| CODE | //Deallocate arrays... for(i=(fa->src.w)-1;i>=0;i--) { free(IpixelB[i]); free(IpixelG[i]); free(IpixelR[i]); } free(IpixelB); free(IpixelG); free(IpixelR); |
-------------------- May the FOURCC be with you... |
 |
| mancanfly |
| Posted: Mar 30 2003, 09:05 PM |
 |
|
Unregistered

|
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
}; _____________________________________________
|
 |
| phaeron |
| Posted: Mar 30 2003, 09:53 PM |
 |
|

Virtualdub Developer
  
Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02

|
src = (Pixel32 *)((char)src + fa->src.modulo);
That should be (char *). |
 |
| fccHandler |
| Posted: Mar 31 2003, 05:50 AM |
 |
|
Administrator n00b
  
Group: Moderators
Posts: 3961
Member No.: 280
Joined: 13-September 02

|
That darn typo devil strikes again!
For sure, next time I will test any code before I post it.
-------------------- May the FOURCC be with you... |
 |
|