|
-
July 2nd, 2012, 05:51 PM
#5
Re: Video player in vc++ (each frame being shown in a new window)
I think this version of "Image.cpp" will make more sense :-
Code:
// Image.cpp : Defines the entry point for the application.
//
#include "Image.h"
MyImage myImage;
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
FILE *IN_FILE;
int flag;
HWND hWnd;
WNDCLASSEX wcex;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
int w, h;
char ImagePath[_MAX_PATH];
sscanf(lpCmdLine, "%s", &ImagePath);
//ImagePath = {"M:\\MediaPlayer\\data\\yuv\\image1.rgb"};
w = 352;
h = 288;
myImage.setWidth(w);
myImage.setHeight(h);
myImage.setImagePath(ImagePath);
flag = 0;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_IMAGE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_IMAGE);
while(1)
{
if(myImage.playFlag==1)
{
myImage.ReadImage();
myImage.ConvertYUVtoRGB();
}
// Code to update the window to be added here. How to use WndProc for updating?
}
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_IMAGE);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_IMAGE;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
//HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDM_PLAY:
myImage.playFlag = 1;
myImage.stopFlag = 0;
break;
case IDM_PAUSE:
myImage.playFlag = 0;
break;
case IDM_STOP:
myImage.playFlag = 1;
myImage.stopFlag = 1;
break;
case ID_CHANNEL_ALL:
myImage.channelNum = 0;
break;
case ID_CHANNEL_Y:
myImage.channelNum = 1;
break;
case ID_CHANNEL_U:
myImage.channelNum = 2;
break;
case ID_CHANNEL_V:
myImage.channelNum = 3;
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
RECT rt;
GetClientRect(hWnd, &rt);
char text[1000];
BITMAPINFO bmi;
CBitmap bitmap;
memset(&bmi,0,sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = myImage.getWidth();
bmi.bmiHeader.biHeight = -myImage.getHeight(); // Use negative height. DIB is top-down.
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = myImage.getWidth()*myImage.getHeight();
SetDIBitsToDevice(hdc,
myImage.getWidth()+50,100,myImage.getWidth(),myImage.getHeight(),
0,0,0,myImage.getHeight(),
myImage.getImageData(),&bmi,DIB_RGB_COLORS);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
// clipper function for range 0 to 255
double ClipRGB(double num)
{
if(num < 0.0)
num = 0.0;
if(num > 255.0)
num = 255.0;
return num;
}
// MyImage functions defined here
void MyImage::ConvertYUVtoRGB()
{
int i;
double iY,iU,iV;
double iR,iG,iB;
NewData = new unsigned char[Width*Height*3];
for(i=0; i<Height*Width; i++)
{
iY = (double) Data[3*i];
iU = (double) Data[3*i+1];
iV = (double) Data[3*i+2];
if(myImage.channelNum == 0) // All channels to be displayed
{
iR = iY + 1.4075*(iV-128.0); /* softpixel.com formula (http://softpixel.com/~cwright/progra...olorspace/yuv/) */
iG = iY - 0.3455*(iU-128.0) - 0.7169*(iV-128.0);
iB = iY + 1.7790*(iU-128.0);
}
else if(myImage.channelNum == 1) // Y channel to be displayed
{
/*iR = iY;
iG = iY;
iB = iY;*/
iR = iY + 1.4075*(128.0-128.0);
iG = iY - 0.3455*(128.0-128.0) - 0.7169*(128.0-128.0);
iB = iY + 1.7790*(128.0-128.0);
}
else if(myImage.channelNum == 2) // U channel to be displayed
{
/*iR = 0.0;
iG = 0.3455*(iU-128.0);
iB = 1.7790*(iU-128.0);*/
iR = iY + 1.4075*(128.0-128.0);
iG = iY - 0.3455*(iU-128.0) - 0.7169*(128.0-128.0);
iB = iY + 1.7790*(iU-128.0);
}
else if(myImage.channelNum == 3) // V channel to be displayed
{
/*iR = 1.4075*(iV-128.0);
iG = 0.0 - 0.7169*(iV-128.0);
iB = 0.0;*/
iR = iY + 1.4075*(iV-128.0);
iG = iY - 0.3455*(128.0-128.0) - 0.7169*(iV-128.0);
iB = iY + 1.7790*(128.0-128.0);
}
iR = ClipRGB(iR); // Clipping of RGB values
iG = ClipRGB(iG);
iB = ClipRGB(iB);
NewData[3*i] = (unsigned char) iB;
NewData[3*i+1] = (unsigned char) iG;
NewData[3*i+2] = (unsigned char) iR;
}
}
void MyImage::ReadImage()
{
int i,j,ctr;
char *Ybuf = new char[Height*Width];
char *Ubuf = new char[Height*Width/4];
char *Vbuf = new char[Height*Width/4];
char *IUbuf = new char[Height*Width/2];
char *IVbuf = new char[Height*Width/2];
char *NewUbuf = new char[Height*Width];
char *NewVbuf = new char[Height*Width];
if(myImage.stopFlag == 1)
{
fclose(IN_FILE);
IN_FILE = fopen(ImagePath, "rb");
if (IN_FILE == NULL)
{
fprintf(stderr, "Error");
exit(0);
}
myImage.playFlag = 0;
}
if(flag == 0)
{
IN_FILE = fopen(ImagePath, "rb");
if (IN_FILE == NULL)
{
fprintf(stderr, "Error");
exit(0);
}
flag = 1;
}
for (i = 0; i < Width*Height; i++)
{
Ybuf[i] = fgetc(IN_FILE);
}
for (i = 0; i < Width*Height/4; i++)
{
Ubuf[i] = fgetc(IN_FILE);
}
for (i = 0; i < Width*Height/4; i++)
{
Vbuf[i] = fgetc(IN_FILE);
}
ctr = 0;
for (i = 0; i < Height/2; i++)
{
for (j = 0; j < Width/2; j++)
{
IUbuf[ctr] = Ubuf[i*Width/2+j];
IUbuf[ctr+Width/2] = Ubuf[i*Width/2+j];
IVbuf[ctr] = Vbuf[i*Width/2+j];
IVbuf[ctr+Width/2] = Vbuf[i*Width/2+j];
ctr++;
}
ctr = ctr + Width/2;
}
ctr = 0;
for (i = 0; i < Width*Height; i+=2)
{
NewUbuf[i] = IUbuf[ctr];
NewUbuf[i+1] = IUbuf[ctr];
NewVbuf[i] = IVbuf[ctr];
NewVbuf[i+1] = IVbuf[ctr];
ctr++;
}
FILE *OUT_FILE;
OUT_FILE = fopen("M:\\uval.txt","w");
char ch= ' ',nl='\n';
for (i = 0; i < Width*Height; i++)
{
fputc( NewUbuf[i], OUT_FILE);
fputc( ch, OUT_FILE);
if( ((i+1)%Width) == 0)
{
fputc( nl, OUT_FILE);
}
}
Data = new unsigned char[Width*Height*3];
for (i = 0; i < Height*Width; i++)
{
Data[3*i] = Ybuf[i];
Data[3*i+1] = NewUbuf[i];
Data[3*i+2] = NewVbuf[i];
/*Data[3*i+1] = (unsigned char) 0;
Data[3*i+2] = (unsigned char) 0;*/
}
delete [] Ybuf;
delete [] Ubuf;
delete [] Vbuf;
//fclose(IN_FILE);
}
In this case whats happening is that InitInstance is being called once and a window is created but I don't know how to update the window with frames. I have WndProc function in my code. How exactly shall I call that function? As in with what parameters? And I shall do that in my while loop just after converting the frame to RGB format right?
Last edited by Marc G; July 3rd, 2012 at 01:57 AM.
Reason: Added code tags
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|