rendering video
-
Following is the piece of code i am using to render grayscale video onto screen. The pixel values are stored as 'int' in the variable disp_frame whose declaration is given below. 50 pixel buffers of size 176 X 144 is used. I thought of creating bitmap out of these pixels and then use BitBlt to render it to the screen. But the CreateDIBSection is creating an exception when running in Debug code. It should be some syntax error. Could anyone debug it out. int p=0,i=0,j=0,q=0; extern int disp_frame[50][144][176]; /////////////////////// BITMAPINFOHEADER bmi; BITMAPINFO bm; RGBQUAD rgbarray[256]; bmi.biSize = sizeof(BITMAPINFOHEADER); bmi.biWidth = 176; bmi.biHeight = 144; bmi.biPlanes = 1; bmi.biBitCount = 8; bmi.biCompression = BI_RGB; bmi.biSizeImage = 0; bmi.biXPelsPerMeter = 0; bmi.biYPelsPerMeter = 0; bmi.biClrUsed = 0; bmi.biClrImportant = 0; bm.bmiHeader = bmi; for (int color_index = 0; color_index < 256; color_index++) { rgbarray[color_index].rgbBlue = i; rgbarray[color_index].rgbGreen = i; rgbarray[color_index].rgbRed = i; rgbarray[color_index].rgbReserved = 0; } bm.bmiColors[1] = rgbarray[0]; ///////////////////// CRect rcClient; GetClientRect(rcClient); // See Note 1 rcClient.right=176; rcClient.bottom=144; /*****************Doubtful routine starts here******* HDC hDC; hDC = CreateDC("DISPLAY",NULL,NULL,NULL); HDC memDC = CreateCompatibleDC(hDC); CreateDIBSection(hDC,bitmap,DIB_PAL_COLORS,ppbits,NULL,0); HBITMAP memBM = CreateCompatibleBitmap(hDC,176,144); SelectObject(memDC,memBM); BitBlt(memDC,150,100,176,144,hDC,0,0,SRCCOPY);
-
Following is the piece of code i am using to render grayscale video onto screen. The pixel values are stored as 'int' in the variable disp_frame whose declaration is given below. 50 pixel buffers of size 176 X 144 is used. I thought of creating bitmap out of these pixels and then use BitBlt to render it to the screen. But the CreateDIBSection is creating an exception when running in Debug code. It should be some syntax error. Could anyone debug it out. int p=0,i=0,j=0,q=0; extern int disp_frame[50][144][176]; /////////////////////// BITMAPINFOHEADER bmi; BITMAPINFO bm; RGBQUAD rgbarray[256]; bmi.biSize = sizeof(BITMAPINFOHEADER); bmi.biWidth = 176; bmi.biHeight = 144; bmi.biPlanes = 1; bmi.biBitCount = 8; bmi.biCompression = BI_RGB; bmi.biSizeImage = 0; bmi.biXPelsPerMeter = 0; bmi.biYPelsPerMeter = 0; bmi.biClrUsed = 0; bmi.biClrImportant = 0; bm.bmiHeader = bmi; for (int color_index = 0; color_index < 256; color_index++) { rgbarray[color_index].rgbBlue = i; rgbarray[color_index].rgbGreen = i; rgbarray[color_index].rgbRed = i; rgbarray[color_index].rgbReserved = 0; } bm.bmiColors[1] = rgbarray[0]; ///////////////////// CRect rcClient; GetClientRect(rcClient); // See Note 1 rcClient.right=176; rcClient.bottom=144; /*****************Doubtful routine starts here******* HDC hDC; hDC = CreateDC("DISPLAY",NULL,NULL,NULL); HDC memDC = CreateCompatibleDC(hDC); CreateDIBSection(hDC,bitmap,DIB_PAL_COLORS,ppbits,NULL,0); HBITMAP memBM = CreateCompatibleBitmap(hDC,176,144); SelectObject(memDC,memBM); BitBlt(memDC,150,100,176,144,hDC,0,0,SRCCOPY);
jossion wrote:
CreateDIBSection(hDC,bitmap,DIB_PAL_COLORS,ppbits,NULL,0);
What is "bitmap"? A BITMAPINFO has a BITMAPINFOHADER in it. It also has 1 of the 256 RGBQUAD structs you need already in it. You need to allocate this all in one contiguous section of memory. The initialization of the color table is wrong, unless you want all black. This line is all wrong and useless - "bm.bmiColors[1] = rgbarray[0];" You are rendering in the wrong direction, unless you're trying to copy pixels from that DISPLAY dc to a memory dc. That "DISPLAY" DC ... why not just use the DC for the client area of a window? You should use DIB_RGB_COLORS when creating the dibsection so the call doesn't overwrite your grayscale color table. You never use the dibsection you create. Something like this should help you create the DIBsection....I don't know what you're trying to render so I can't provide an example for that until you clear that up :)...
BITMAPINFO \*bm = (BITMAPINFO \*)new BYTE\[sizeof(BITMAPINFO) + 255 \* sizeof(RGBQUAD)\];
bm->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bm->bmiHeader.biWidth = 176;
bm->bmiHeader.biHeight = 144;
bm->bmiHeader.biPlanes = 1;
bm->bmiHeader.biBitCount = 8;
bm->bmiHeader.biCompression = BI_RGB;
bm->bmiHeader.biSizeImage = 0;
bm->bmiHeader.biXPelsPerMeter = 0;
bm->bmiHeader.biYPelsPerMeter = 0;
bm->bmiHeader.biClrUsed = 0;
bm->bmiHeader.biClrImportant = 0;for (int color_index = 0; color_index < 256; color_index++)
{
bm->bmiColors[color_index].rgbBlue = color_index; // this goes from black to white - use "255-color_index" to go from white to black
bm->bmiColors[color_index].rgbGreen = color_index; // this goes from black to white - use "255-color_index" to go from white to black
bm->bmiColors[color_index].rgbRed = color_index; // this goes from black to white - use "255-color_index" to go from white to black
bm->bmiColors[color_index].rgbReserved = 0;
}&
-
jossion wrote:
CreateDIBSection(hDC,bitmap,DIB_PAL_COLORS,ppbits,NULL,0);
What is "bitmap"? A BITMAPINFO has a BITMAPINFOHADER in it. It also has 1 of the 256 RGBQUAD structs you need already in it. You need to allocate this all in one contiguous section of memory. The initialization of the color table is wrong, unless you want all black. This line is all wrong and useless - "bm.bmiColors[1] = rgbarray[0];" You are rendering in the wrong direction, unless you're trying to copy pixels from that DISPLAY dc to a memory dc. That "DISPLAY" DC ... why not just use the DC for the client area of a window? You should use DIB_RGB_COLORS when creating the dibsection so the call doesn't overwrite your grayscale color table. You never use the dibsection you create. Something like this should help you create the DIBsection....I don't know what you're trying to render so I can't provide an example for that until you clear that up :)...
BITMAPINFO \*bm = (BITMAPINFO \*)new BYTE\[sizeof(BITMAPINFO) + 255 \* sizeof(RGBQUAD)\];
bm->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bm->bmiHeader.biWidth = 176;
bm->bmiHeader.biHeight = 144;
bm->bmiHeader.biPlanes = 1;
bm->bmiHeader.biBitCount = 8;
bm->bmiHeader.biCompression = BI_RGB;
bm->bmiHeader.biSizeImage = 0;
bm->bmiHeader.biXPelsPerMeter = 0;
bm->bmiHeader.biYPelsPerMeter = 0;
bm->bmiHeader.biClrUsed = 0;
bm->bmiHeader.biClrImportant = 0;for (int color_index = 0; color_index < 256; color_index++)
{
bm->bmiColors[color_index].rgbBlue = color_index; // this goes from black to white - use "255-color_index" to go from white to black
bm->bmiColors[color_index].rgbGreen = color_index; // this goes from black to white - use "255-color_index" to go from white to black
bm->bmiColors[color_index].rgbRed = color_index; // this goes from black to white - use "255-color_index" to go from white to black
bm->bmiColors[color_index].rgbReserved = 0;
}&
I have pixel values of successive frames of video stored in int disp_frame[50][144[176], 50 buffers of size 176X144. Under a timer of 40ms I was doing all the stuff which i posted. Previously I was using setpixel to draw the video. Now for better speed I thought of doing BitBlt. So there came a ncessity to convert the raw pixel values to bitmap. That is what should happen in the rendering section. Creating DC,then Creating DIB then copying to memory DC, then using BitBlt or optional zooming with StretchBlt. I know that there are still excellent ways of doing it. But I thought of learning all techniques by coding it and seeing the performance. So I would like you to fill the rendering area with BitBlt(including routines for DC creation) for displaying pixels in disp_frame.As I have read the pixel values should be copied to (void**)&pBitmapBits. Basically I am not a person with programming background. that's why my code might have irritated you a bit. Anyhow a small apology for my mistakes. bitmap is of type BITMAPINFO *bitmap.
-
I have pixel values of successive frames of video stored in int disp_frame[50][144[176], 50 buffers of size 176X144. Under a timer of 40ms I was doing all the stuff which i posted. Previously I was using setpixel to draw the video. Now for better speed I thought of doing BitBlt. So there came a ncessity to convert the raw pixel values to bitmap. That is what should happen in the rendering section. Creating DC,then Creating DIB then copying to memory DC, then using BitBlt or optional zooming with StretchBlt. I know that there are still excellent ways of doing it. But I thought of learning all techniques by coding it and seeing the performance. So I would like you to fill the rendering area with BitBlt(including routines for DC creation) for displaying pixels in disp_frame.As I have read the pixel values should be copied to (void**)&pBitmapBits. Basically I am not a person with programming background. that's why my code might have irritated you a bit. Anyhow a small apology for my mistakes. bitmap is of type BITMAPINFO *bitmap.
First, your code didn't irritate me. You stated "Could anyone debug it out." and I tried to do that. :) Here's a breakdown of the rendering problem... SetPixel is a really bad choice for rendering video, so moving to a bit-block-transfer implementation is the right direction. To use BitBlt()/StretchBlt(), you need a source DC with a bitmap containing the pixels you want to render selected into it. Since your pixel data comes in raw int format, you need a HBITMAP bitmap that allows you direct access to its pixel data - thats what a DIBSection is for. Once you have all that, there's more that can be optimized - You don't have to recreate the DIB section every time you render a frame. It can be created once, before you start rendering frames. Same applies to the memory DC - it only needs to be created once and have the DIBSection selected into it. That means every 40ms, you only need to copy the pixel bits to the DIBSection, get a destination DC for where you're going to draw, and blt. Here's an expanded example...
// Video renderer variables
extern int disp_frame[50][144][176];
LONG VideoWidth = 176;
LONG VideoHeight = 144;
WORD BitsPerPixel = 8;
LONG BytesPerDIBSectionRow = (((VideoWidth * (long)BitsPerPixel + 31L) & (~31L)) / 8L);
BITMAPINFO *pBMI = 0;
BYTE *pBitmapBits = 0;
HBITMAP hDIBSection = 0;
HGDIOBJ hOldMemBitmap = 0;
HDC memDC = 0;bool InitVideoRenderer()
{
pBMI = (BITMAPINFO *)new BYTE[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)];pBMI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBMI->bmiHeader.biWidth = VideoWidth;
pBMI->bmiHeader.biHeight = VideoHeight;
pBMI->bmiHeader.biPlanes = 1;
pBMI->bmiHeader.biBitCount = BitsPerPixel;
pBMI->bmiHeader.biCompression = BI_RGB;
pBMI->bmiHeader.biSizeImage = 0;
pBMI->bmiHeader.biXPelsPerMeter = 0;
pBMI->bmiHeader.biYPelsPerMeter = 0;
pBMI->bmiHeader.biClrUsed = 0;
pBMI->bmiHeader.biClrImportant = 0;for (int color_index = 0; color_index < 256; color_index++)
{
pBMI->bmiColors[color_index].rgbBlue = color_index;
pBMI->bmiColors[color_index].rgbGreen = color_index;
pBMI->bmiCol -
First, your code didn't irritate me. You stated "Could anyone debug it out." and I tried to do that. :) Here's a breakdown of the rendering problem... SetPixel is a really bad choice for rendering video, so moving to a bit-block-transfer implementation is the right direction. To use BitBlt()/StretchBlt(), you need a source DC with a bitmap containing the pixels you want to render selected into it. Since your pixel data comes in raw int format, you need a HBITMAP bitmap that allows you direct access to its pixel data - thats what a DIBSection is for. Once you have all that, there's more that can be optimized - You don't have to recreate the DIB section every time you render a frame. It can be created once, before you start rendering frames. Same applies to the memory DC - it only needs to be created once and have the DIBSection selected into it. That means every 40ms, you only need to copy the pixel bits to the DIBSection, get a destination DC for where you're going to draw, and blt. Here's an expanded example...
// Video renderer variables
extern int disp_frame[50][144][176];
LONG VideoWidth = 176;
LONG VideoHeight = 144;
WORD BitsPerPixel = 8;
LONG BytesPerDIBSectionRow = (((VideoWidth * (long)BitsPerPixel + 31L) & (~31L)) / 8L);
BITMAPINFO *pBMI = 0;
BYTE *pBitmapBits = 0;
HBITMAP hDIBSection = 0;
HGDIOBJ hOldMemBitmap = 0;
HDC memDC = 0;bool InitVideoRenderer()
{
pBMI = (BITMAPINFO *)new BYTE[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)];pBMI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBMI->bmiHeader.biWidth = VideoWidth;
pBMI->bmiHeader.biHeight = VideoHeight;
pBMI->bmiHeader.biPlanes = 1;
pBMI->bmiHeader.biBitCount = BitsPerPixel;
pBMI->bmiHeader.biCompression = BI_RGB;
pBMI->bmiHeader.biSizeImage = 0;
pBMI->bmiHeader.biXPelsPerMeter = 0;
pBMI->bmiHeader.biYPelsPerMeter = 0;
pBMI->bmiHeader.biClrUsed = 0;
pBMI->bmiHeader.biClrImportant = 0;for (int color_index = 0; color_index < 256; color_index++)
{
pBMI->bmiColors[color_index].rgbBlue = color_index;
pBMI->bmiColors[color_index].rgbGreen = color_index;
pBMI->bmiCol -
thank you very much. This is the first time I am getting a complete solution from Codeproject. cheers.
No problem! I just realized I treated your source data as 16bpp when it's 32bpp (int!) LOL I'll change that. Cheers, Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
No problem! I just realized I treated your source data as 16bpp when it's 32bpp (int!) LOL I'll change that. Cheers, Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
Hi Salsbery, For the past one year the piece of code you gave me satisfied my requirements excellently. Now I have come up with a problem of displaying colour video. I will need help once again in modifying the code to colour. The main problem is how I should arrange the pixels and where to write it. What are the BITMAPINFO parameters that I have to change. Hope to get a reply at the earliest.
-
Hi Salsbery, For the past one year the piece of code you gave me satisfied my requirements excellently. Now I have come up with a problem of displaying colour video. I will need help once again in modifying the code to colour. The main problem is how I should arrange the pixels and where to write it. What are the BITMAPINFO parameters that I have to change. Hope to get a reply at the earliest.
jossion wrote:
modifying the code to colour
How many bits per pixel? Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
jossion wrote:
modifying the code to colour
How many bits per pixel? Mark
Mark Salsbery Microsoft MVP - Visual C++ :java: