avi_write.cpp

Go to the documentation of this file.
00001 #pragma warning( disable : 4311 4312 4133)
00002 
00003 
00004 #define _WIN32_DCOM 
00005 
00006 #include <atlbase.h>
00007 #include <windows.h>
00008 #include <dshow.h>
00009 #include <stdio.h>
00010 #include <streams.h>
00011 
00012 #include "avi_write.h"
00013 #include "avi_PushSource.h"
00014 
00015 extern BOOL DoDialog(HINSTANCE hInstance, HWND hWnd);
00016 extern void CentreDialogOnScreen(HWND);
00017 
00018 HWND ghApp=0;
00019 DWORD g_dwGraphRegister=0;
00020 
00021 int gFirstF;
00022 int gLastF;
00023 int gCurrentF;  
00024 
00025 BOOL bCompressed=TRUE;
00026 
00027 HRESULT BuildFilterGraph(HINSTANCE hInstance, char *ffn);
00028 
00029 IVideoWindow  * g_pVW = NULL;
00030 IMediaControl * g_pMC = NULL;
00031 IMediaEventEx * g_pME = NULL;
00032 IGraphBuilder * g_pGraph = NULL;
00033 IBaseFilter   * g_pMux=NULL;
00034 IBaseFilter   * g_pVComp=NULL;
00035 ICaptureGraphBuilder2 * g_pCapture = NULL;
00036 PLAYSTATE g_psCurrent = Stopped;
00037 
00038 
00039 HRESULT GetInterfaces(void){
00040     HRESULT hr;
00041     hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC,
00042                            IID_IGraphBuilder, (void **) &g_pGraph);
00043     if (FAILED(hr))        return hr;
00044     hr = CoCreateInstance (CLSID_CaptureGraphBuilder2 , NULL, CLSCTX_INPROC,
00045                            IID_ICaptureGraphBuilder2, (void **) &g_pCapture);
00046     if (FAILED(hr))        return hr;
00047     hr = g_pGraph->QueryInterface(IID_IMediaControl,(LPVOID *) &g_pMC);
00048     if (FAILED(hr))        return hr;
00049     hr = g_pGraph->QueryInterface(IID_IVideoWindow, (LPVOID *) &g_pVW);
00050     if (FAILED(hr))        return hr;
00051     hr = g_pGraph->QueryInterface(IID_IMediaEvent, (LPVOID *) &g_pME);
00052     if (FAILED(hr))        return hr;
00053     hr = g_pME->SetNotifyWindow((OAHWND)ghApp, WM_GRAPHNOTIFY, 0);
00054     return hr;
00055 }
00056 
00057 void CloseInterfaces(void){
00058     // Stop previewing data
00059     if (g_pMC)        g_pMC->StopWhenReady();
00060     g_psCurrent = Stopped;
00061     if (g_pME)        g_pME->SetNotifyWindow(NULL, WM_GRAPHNOTIFY, 0);
00062     if(g_pVW){
00063         g_pVW->put_Visible(OAFALSE);
00064         g_pVW->put_Owner(NULL);
00065     }
00066     SAFE_RELEASE(g_pMC);
00067     SAFE_RELEASE(g_pME);
00068     SAFE_RELEASE(g_pVW);
00069     SAFE_RELEASE(g_pMux);
00070     SAFE_RELEASE(g_pVComp);
00071     SAFE_RELEASE(g_pGraph);
00072     SAFE_RELEASE(g_pCapture);
00073 }
00074 
00075 HRESULT SetupVideoWindow(void){
00076     HRESULT hr;
00077     hr = g_pVW->put_Owner((OAHWND)ghApp);
00078     if (FAILED(hr))        return hr;
00079     hr = g_pVW->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
00080     if (FAILED(hr))        return hr;
00081     ResizeVideoWindow();
00082     hr = g_pVW->put_Visible(OATRUE);
00083     if (FAILED(hr))        return hr;
00084     return hr;
00085 }
00086 
00087 void ResizeVideoWindow(void){
00088     if (g_pVW){
00089         RECT rc;
00090         GetClientRect(ghApp, &rc);
00091         g_pVW->SetWindowPosition(0, 0, rc.right, rc.bottom);
00092     }
00093 }
00094 
00095 HRESULT ChangePreviewState(int nShow){
00096     HRESULT hr=S_OK;
00097     // If the media control interface isn't ready, don't call it
00098     if (!g_pMC)        return S_OK;
00099     if (nShow)    {
00100         if (g_psCurrent != Running){
00101             // Start previewing video data
00102             hr = g_pMC->Run();
00103             g_psCurrent = Running;
00104         }
00105     }
00106     else    {
00107         // Stop previewing video data
00108         hr = g_pMC->StopWhenReady();
00109         g_psCurrent = Stopped;
00110     }
00111     return hr;
00112 }
00113 
00114 void Msg(TCHAR *szFormat, ...){
00115     TCHAR szBuffer[1024];  // Large buffer for long filenames or URLs
00116     const size_t NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]);
00117     const int LASTCHAR = NUMCHARS - 1;
00118     va_list pArgs;
00119     va_start(pArgs, szFormat);
00120     _vsntprintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
00121     va_end(pArgs);
00122     szBuffer[LASTCHAR] = TEXT('\0');
00123     MessageBox(NULL, szBuffer, TEXT("PlayCap Message"), MB_OK | MB_ICONERROR);
00124 }
00125 
00126 
00127 HRESULT HandleGraphEvent(void){
00128     LONG evCode, evParam1, evParam2;
00129     HRESULT hr=S_OK;
00130     if (!g_pME)
00131         return E_POINTER;
00132     while(SUCCEEDED(g_pME->GetEvent(&evCode, (LONG_PTR *) &evParam1, 
00133                    (LONG_PTR *) &evParam2, 0)))    {
00134         switch (evCode){
00135           case EC_COMPLETE:
00136             //MessageBox(NULL,"Complete","Output",MB_OK);
00137             PostMessage(ghApp,WM_CLOSE,0,0); 
00138             break;
00139           case EC_ERRORABORT:
00140             //MessageBox(NULL,"Error","Output",MB_OK);
00141             break;
00142 
00143         }
00144         //
00145         // Free event parameters to prevent memory leaks associated with
00146         // event parameter data.  While this application is not interested
00147         // in the received events, applications should always process them.
00148         //
00149         hr = g_pME->FreeEventParams(evCode, evParam1, evParam2);
00150         // Insert event processing code here, if desired
00151     }
00152     return hr;
00153 }
00154 
00155 
00156 LRESULT CALLBACK WndMainProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
00157     switch (message){
00158         case WM_CREATE:
00159             CentreDialogOnScreen(hwnd);
00160             break;
00161         case WM_GRAPHNOTIFY:
00162             HandleGraphEvent();
00163             break;
00164         case WM_SIZE:
00165             ResizeVideoWindow();
00166             break;
00167         case WM_PAINT:{
00168               HDC hDC;
00169               PAINTSTRUCT  ps;
00170               hDC = BeginPaint(hwnd, &ps); // Gcurrent Frame
00171               char strx[100]; 
00172               sprintf(strx,"Building Movie");
00173               TextOut(hDC,5,4,strx,(int)strlen(strx));
00174               sprintf(strx,"Please Wait ..");
00175               TextOut(hDC,5,20,strx,(int)strlen(strx));
00176               EndPaint(hwnd, &ps);
00177             }
00178             break;
00179         case WM_WINDOWPOSCHANGED:
00180             ChangePreviewState(! (IsIconic(hwnd)));
00181             break;
00182         case WM_CLOSE:            
00183             // Hide the main window while the graph is destroyed
00184             ShowWindow(ghApp, SW_HIDE);
00185             CloseInterfaces();  // Stop capturing and release interfaces
00186             break;
00187         case WM_DESTROY:
00188             //MessageBox(NULL,"Window Destroyed",NULL,MB_OK);
00189             PostQuitMessage(0);
00190             return 0;
00191     }
00192     // Pass this message to the video window for notification of system changes
00193     if (g_pVW)
00194         g_pVW->NotifyOwnerMessage((LONG_PTR) hwnd, message, wParam, lParam);
00195     return DefWindowProc (hwnd , message, wParam, lParam);
00196 }
00197 
00198 void  CreateCompressionFilter(IMoniker *pMoniker, BOOL dvPal){
00199   HRESULT hr;
00200   hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, 
00201                                        (void**)&g_pVComp);
00202   if (FAILED(hr)){MessageBox(NULL,"Failed to create compression Filter",NULL,MB_OK); return;}
00203   if(!dvPal)return;
00204   IDVEnc * pDVEnc=NULL;
00205   hr = g_pVComp->QueryInterface(IID_IDVEnc, (LPVOID *) &pDVEnc);
00206   if (FAILED(hr)){
00207     MessageBox(NULL,"Failed to Get IDVENC interface",NULL,MB_OK);
00208     return;
00209   }
00210   hr =  pDVEnc->put_IFormatResolution(DVENCODERVIDEOFORMAT_PAL,
00211                                       DVENCODERFORMAT_DVSD,
00212                                       DVENCODERRESOLUTION_720x480,
00213                                       FALSE,NULL);  
00214   if (FAILED(hr))MessageBox(NULL,"Failed to Set Resolution",NULL,MB_OK);
00215   SAFE_RELEASE(pDVEnc);
00216   return;
00217 }
00218 
00219 
00220 extern "C"  int AVIEntryPoint(HINSTANCE hInstance, long first_file, long last_file, 
00221                               char *avi_outname){
00222     MSG msg={0};
00223     int rval=1;
00224     WNDCLASS wc;
00225     if(FAILED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))    {
00226         Msg(TEXT("CoInitialize Failed!\r\n"));   
00227         exit(1);
00228     } 
00229     ZeroMemory(&wc, sizeof wc);
00230     wc.lpfnWndProc   = WndMainProc;
00231     wc.hInstance     = hInstance;
00232     wc.lpszClassName = CLASSNAME;
00233     wc.lpszMenuName  = NULL;
00234     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
00235     wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
00236     wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_VIDPREVIEW));
00237     if(!RegisterClass(&wc))    {
00238         Msg(TEXT("RegisterClass Failed! Error=0x%x\r\n"), GetLastError());
00239         CoUninitialize();
00240         exit(1);
00241     }
00242     ghApp = CreateWindow(CLASSNAME, APPLICATIONNAME,
00243                          WS_OVERLAPPEDWINDOW | WS_CAPTION | WS_CLIPCHILDREN,
00244                          CW_USEDEFAULT, CW_USEDEFAULT,
00245                          DEFAULT_VIDEO_WIDTH, DEFAULT_VIDEO_HEIGHT,
00246                          0, 0, hInstance, 0);
00247     gFirstF = first_file;
00248     gLastF = last_file;
00249     {
00250       HRESULT hr;
00251       if(DoDialog(hInstance,NULL)){
00252         hr = BuildFilterGraph(hInstance,avi_outname);
00253         if (FAILED (hr)) {
00254             CloseInterfaces();
00255             DestroyWindow(ghApp);
00256         }
00257         else{
00258             ShowWindow(ghApp,SW_SHOW);
00259         }
00260       } 
00261       else {
00262         rval=0;
00263         DestroyWindow(ghApp);
00264       }
00265       while(GetMessage(&msg,NULL,0,0))        {
00266           TranslateMessage(&msg);
00267           DispatchMessage(&msg);
00268       }
00269     }
00270 
00271     if(UnregisterClass(CLASSNAME,hInstance) == 0){
00272       MessageBox(NULL,"Unregister Class Failed",NULL,MB_OK);
00273     }
00274     //MessageBox(NULL,"Entry terminated",NULL,MB_OK);
00275     CoUninitialize();
00276     return (int)rval;
00277 }
00278 
00279 
00280 HRESULT BuildFilterGraph(HINSTANCE hInstance, char *ffn){
00281     USES_CONVERSION;
00282     HRESULT hr;
00283     char MediaOutput[256];
00284     CComPtr<IBaseFilter> pSource;      // Texture Renderer Filter
00285 //    IBaseFilter *pSource;
00286     CPushSourceBitmapSet *pCTR=0;  
00287     strcpy(MediaOutput,ffn);
00288     hr = GetInterfaces();
00289     if (FAILED(hr)){
00290         Msg(TEXT("Failed to get video interfaces!  hr=0x%x"), hr);
00291         return hr;
00292     }
00293     hr = g_pCapture->SetFiltergraph(g_pGraph);
00294     if (FAILED(hr))    {
00295         Msg(TEXT("Failed to set capture filter graph!  hr=0x%x"), hr);
00296         return hr;
00297     }
00298     // put in our in place filter 
00299     pCTR = new CPushSourceBitmapSet(0,NULL, &hr);
00300     pSource=pCTR;
00301     hr = g_pGraph->AddFilter(pSource, L"Video Capture");
00302     if (FAILED(hr))    {
00303         Msg(TEXT("Couldn't add the capture filter to the graph!  hr=0x%x\r\n\r\n") 
00304             TEXT("The sample will now close."), hr);
00305         return hr;
00306     }
00307     hr = g_pCapture->SetOutputFileName(
00308            &MEDIASUBTYPE_Avi,  // Specifies AVI for the target file.
00309             A2W(MediaOutput),
00310             &g_pMux,              // Receives a pointer to the AVI mux.
00311             NULL);              // (Optional) Receives a pointer to the file sink.
00312     if (FAILED(hr)){
00313           Msg(TEXT("Failed to set Output filename!  hr=0x%x"), hr);
00314           return hr;
00315     }
00316     if(bCompressed && g_pVComp != NULL){
00317       hr=g_pGraph->AddFilter(g_pVComp,L"recompress");
00318       if (FAILED(hr))    {
00319          Msg(TEXT("Failed to add the compression filter: hr=0x%x"), hr);
00320          return hr;
00321       }
00322       hr = g_pCapture->RenderStream(0,0,pSource,g_pVComp,g_pMux);
00323     }
00324     else{
00325       hr = g_pCapture->RenderStream(0,0,pSource,0,g_pMux);
00326     }
00327     if (FAILED(hr)){ Msg("Fail to connect Mux"); return hr;}
00328 
00329     // Start previewing video data
00330 //MessageBox(NULL,"Graph Running",NULL,MB_OK);
00331     hr = g_pMC->Run();
00332     if (FAILED(hr))    {
00333         Msg(TEXT("Couldn't run the graph!  hr=0x%x"), hr);
00334         return hr;
00335     }
00336     // Remember current state
00337     g_psCurrent = Running;
00338     return S_OK;
00339 }

Generated on Sun Apr 27 14:20:13 2014 for OpenFX by  doxygen 1.5.6