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
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
00098 if (!g_pMC) return S_OK;
00099 if (nShow) {
00100 if (g_psCurrent != Running){
00101
00102 hr = g_pMC->Run();
00103 g_psCurrent = Running;
00104 }
00105 }
00106 else {
00107
00108 hr = g_pMC->StopWhenReady();
00109 g_psCurrent = Stopped;
00110 }
00111 return hr;
00112 }
00113
00114 void Msg(TCHAR *szFormat, ...){
00115 TCHAR szBuffer[1024];
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
00137 PostMessage(ghApp,WM_CLOSE,0,0);
00138 break;
00139 case EC_ERRORABORT:
00140
00141 break;
00142
00143 }
00144
00145
00146
00147
00148
00149 hr = g_pME->FreeEventParams(evCode, evParam1, evParam2);
00150
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);
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
00184 ShowWindow(ghApp, SW_HIDE);
00185 CloseInterfaces();
00186 break;
00187 case WM_DESTROY:
00188
00189 PostQuitMessage(0);
00190 return 0;
00191 }
00192
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
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;
00285
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
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,
00309 A2W(MediaOutput),
00310 &g_pMux,
00311 NULL);
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
00330
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
00337 g_psCurrent = Running;
00338 return S_OK;
00339 }