Implement your own Algorithm into a DirectShow Filter
A MontiVision Filter SDK
DLL contains one function which is provided for the
implementation of custom algorithms, the TransformSample()
function. This function is called for every
frame passing the filter in a started filter
configuration. The function provides two pointers
to arrays of bytes, one array contains the
input and the other one the output image. The
arrays are of the same size. Your new DirectShow filter reads
the data from the input image buffer, processes it and writes the
resulting data into the output image buffer.To help you navigating
through the image, a couple of additional parameters are
passed to the function. The iWidth and the iHeight parameters
contain the dimension of the image. It is not possible
to change the input image to a smaller or larger output
image size. The iBytePerPixel parameter defines the
number of bytes used per pixel. There are three possible values: 1
(grayscale), 3 (RGB in byte order B G R) or 4 (ARGB in byte
order B G R A). The input and output images have the same
number of bytes per pixel. It is not possible to change the color
depth of the output image. The global variable g_dwTypes sets the
possible video formats the filter accepts.
Image Organization
Input and output images are stored in a
one-dimensional buffer of type BYTE, where a BYTE is an
unsigned 8 bit value. Each pixel of the image contains
one, three or four bytes. The number of bytes per pixel depends on
the color bit depth of the image.
| RGB_8 |
1 |
| RGB_24 |
3 |
| RGB_32 |
4 |
The pixels are encoded as RGB(A)
values. The image buffer is organized in lines. In a RGB24 image,
the first pixel of the first line of the image is represented
in the array as the first three values of the array, the following
three values represent the next pixel of the image and so on. Each
line of the image is DWORD aligned. The first line in the array is
followed by the second line and so on. The first line of the array
is the bottom line of the image. This image layout used
in DirectShow® is different from the layout used in
Windows bitmaps and Windows GDI. The color values for a pixel
are stored in the order: blue, green, red,
alpha.
Sample:
The easiest way to understand this is through a diagram.
Below you see a 2x2 pixel image in RGB 24 mode.
Image:
RGB
Line 2
Pixel 1 |
RGB
Line 2
Pixel 2 |
RGB
Line 1
Pixel 1 |
RGB
Line 1
Pixel 2 |
Array:
| image[0] |
image[1] |
image[2] |
image[3] |
image[4] |
image[5] |
image[6] |
image[7] |
image[8] |
image[9] |
image[10] |
image[11] |
image[12] |
image[13] |
image[14] |
image[15] |
Blue value
Pixel 1
Line 1 |
Green
value
Pixel 1
Line 1 |
Red value
Pixel 1
Line 1 |
Blue value
Pixel 2
Line 1 |
Green value
Pixel 2
Line 1 |
Red value
Pixel 2
Line 1 |
padding
for
DWORD alignment
|
padding
for
DWORD alignment
|
Blue value
Pixel 1
Line 2 |
Green value
Pixel 1
Line 2 |
Red value
Pixel 1
Line 2 |
Blue value
Pixel 2
Line 2 |
Green value
Pixel 2
Line 2 |
Red value
Pixel 2
Line 2 |
padding
for
DWORD allignment |
padding
for
DWORD
allignment |
Because of the DWORD alignment one line of
the image is stored in 8 bytes. The iPitch parameter of the
TransformSample function is set to 8.
Sample
This is a working TransformSample()
function. It reads a parameter from the parameter structure
(*pSavePointer) which was initialized in the function
InitDLL() . Three
"for" loops go through the input image and copy
the bytes of every pixel to the output image.
STDAPI TransformSample(
BYTE*
pInBuffer,
BYTE*
pOutBuffer,
int
iWidth,
int
iHeight,
int
iBytePerPixel,
int
iPitch
void* pSavePointer,
void*
pTempPointer,
PVOID
pIOInBuffer,
int iIOInBufferSize,
PVOID pIOOutBuffer,
int
iIOOutBufferSize,
SAMPLE_TIMES times)
{
int i, j;
int iParam = 0;
int iTemp = 0;
iParam =
((FILTER_PARAMETER*)pSavePointer)->iParam;
iTemp =
++((FILTER_TEMP_DATA*)pTempPointer)->iTemp;
// Sample
for IO_UINT8 I/O input pin type
BYTE invalue;
if((pIOInBuffer != 0L) &&
(iIOInBufferSize >= sizeof(BYTE)))
{
invalue =
*((BYTE*)pIOInBuffer);
}
for( i=0; i<iHeight; i++ )
{
for( j=0;
j<iPitch; j++ )
{
*pOutBuffer++ = *pInBuffer++;
}
}
// Sample for IO_STRING I/O output pin
type
char* outvalue;
if((pIOOutBuffer != 0L) &&
(iIOOutBufferSize >= 256))
{
outvalue =
(char*)pIOOutBuffer;
StringCchPrintf(outvalue, "Input Value: 0x%02X, frame %d", invalue,
iTemp);
}
return S_OK;
}
|