CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9

Threaded View

  1. #5
    Join Date
    Jun 2012
    Posts
    8

    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
  •  





Click Here to Expand Forum to Full Width

Featured