DirectShow


DirectShow

It is a set of APIs for multimedia to perform operations with media files (audio and video) or streams.
Es un conjunto de APis para multimedia para realizar operaciones con archivos de media (sonido y video).

Problem 1
Create a Wintempla Window application called MyVideoX to test a digital video camera. After creating the application, select the App event (WM_APP), Close (WM_CLOSE), Size (WM_SIZE) and WindowPosChanged (WM_WINDOWPOSCHANGED) as shown.
Cree una aplicación de Ventana de Wintempla llamada MyVideoX para probar una cámara de video digital. Después de crear la aplicación, selecciona el evento App (WM_APP), Close (WM_CLOSE), Size (WM_SIZE), WindowPosChanged (WM_WINDOWPOSCHANGED) cómo se muestra.

MyVideoXEvent

Step A
Edit the stdafx.h file as shown. Add the following code at the end of the file.
Edite el archivo stdafx.h cómo se muestra. Agregue el siguiente código al final del archivo.

stdafx.h
...
//_____________________________________________________ DirectShow Libraries
#include "Dshow.h"
#pragma comment(lib, "Strmiids.lib")
_COM_SMARTPTR_TYPEDEF(ICaptureGraphBuilder2, __uuidof(ICaptureGraphBuilder2));
_COM_SMARTPTR_TYPEDEF(IGraphBuilder, __uuidof(IGraphBuilder));
_COM_SMARTPTR_TYPEDEF(IFilterGraph, __uuidof(IFilterGraph));
_COM_SMARTPTR_TYPEDEF(IEnumMoniker, __uuidof(IEnumMoniker));
_COM_SMARTPTR_TYPEDEF(IMoniker, __uuidof(IMoniker));
_COM_SMARTPTR_TYPEDEF(IPropertyBag, __uuidof(IPropertyBag));
_COM_SMARTPTR_TYPEDEF(IMediaControl, __uuidof(IMediaControl));
_COM_SMARTPTR_TYPEDEF(IVideoWindow, __uuidof(IVideoWindow));
_COM_SMARTPTR_TYPEDEF(IMediaEventEx, __uuidof(IMediaEventEx));
_COM_SMARTPTR_TYPEDEF(IBaseFilter, __uuidof(IBaseFilter));
_COM_SMARTPTR_TYPEDEF(ICreateDevEnum, __uuidof(ICreateDevEnum));


Step B
Edit the files MyVideoX.h and MyVideoX.cpp.
Edite los archivos MyVideoX.h y MyVideoX.cpp.

MyVideoX.h
#pragma once //______________________________________ MyVideoX.h
#include "Resource.h"
class MyVideoX: public Win::Window
{
public:
     MyVideoX()
     {
          ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
          graphBuilder = NULL;
          captureGraphBuilder2 = NULL;
          filterGraph = NULL;     
          mediaControl = NULL;
          videoWindow = NULL;
          mediaEventEx = NULL;
          playState = Stopped;
     }
     ~MyVideoX()
     {
          mediaEventEx = NULL;
          videoWindow = NULL;
          mediaControl = NULL;     
          filterGraph = NULL;
          captureGraphBuilder2 = NULL;
          graphBuilder = NULL;
          ::CoUninitialize();
     }
     enum PLAYSTATE { Stopped, Paused, Running, Init };
     IGraphBuilderPtr graphBuilder;
     ICaptureGraphBuilder2Ptr captureGraphBuilder2;
     IFilterGraphPtr filterGraph;
     IMediaControlPtr mediaControl;
     IVideoWindowPtr videoWindow;
     IMediaEventExPtr mediaEventEx;
     PLAYSTATE playState = Stopped;
     //
     bool GetFirstVideoDevice(IBaseFilterPtr& baseFilter);
     HRESULT SetupVideoWindow();
     void ResizeVideoWindow();
     ...
};


MyCap.cpp
...
void MyVideoX::Window_Open(Win::Event& e)
{
     HRESULT hr;
     //____________________________________________________ 1. Create the ICaptureGraphBuilder2
     hr = captureGraphBuilder2.CreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC);
     if (FAILED(hr))
     {
          this->MessageBox(L"Unable to create ICaptureGraphBuilder2", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________ 2. Create the IFilterGraph
     hr = filterGraph.CreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC);
     if (FAILED(hr))
     {
          this->MessageBox(L"Unable to create IFilterGraph", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________ 3. Get a IGraphBuilder
     graphBuilder = filterGraph;
     if (graphBuilder == NULL)
     {
          this->MessageBox(L"Unable to get IGraphBuilder", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________ 4. Get a IMediaControl interface
     mediaControl = filterGraph;
     if (mediaControl == NULL)
     {
          this->MessageBox(L"Unable to get IMediaControl", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________ 5. Get a IVideoWindow interface
     videoWindow = filterGraph;
     if (videoWindow == NULL)
     {
          this->MessageBox(L"Unable to get IVideoWindow", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________ 6. Get a IMediaEventEx interface
     mediaEventEx = filterGraph;
     if (mediaEventEx == NULL)
     {
          this->MessageBox(L"Unable to get IMediaEventEx", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     hr = mediaEventEx->SetNotifyWindow((OAHWND)hWnd, WM_APP, 0);
     if (FAILED(hr))
     {
          this->MessageBox(L"Error mediaEventEx->SetNotifyWindow", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________ 7. Attach the IFilterGraph to the ICaptureGraphBuilder2
     hr = captureGraphBuilder2->SetFiltergraph(graphBuilder);
     if (FAILED(hr))
     {
          this->MessageBox(L"Error captureGraphBuilder2->SetFiltergraph", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     //_____________________________________________________ 8. Set window handle used to process graph events     
     IBaseFilterPtr baseFilter;
     if (GetFirstVideoDevice(baseFilter) == false)
     {
          this->MessageBox(L"No video device is available", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     //_____________________________________________________ 9. RenderStream
     hr = captureGraphBuilder2->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
          baseFilter, NULL, NULL);
     if (FAILED(hr))
     {
          this->MessageBox(L"The capture device may already be in use by another application.", L"MyVideoX", MB_OK | MB_ICONERROR);     
          return;
     }
     baseFilter = NULL;
     hr = SetupVideoWindow();
     if (FAILED(hr))
     {
          this->MessageBox(L"Couldn't initialize video window!", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
//#ifdef REGISTER_FILTERGRAPH
//     // Add our graph to the running object table, which will allow
//     // the GraphEdit application to "spy" on our graph
//     hr = AddGraphToRot(g_pGraph, &g_dwGraphRegister);
//     if (FAILED(hr))
//     {
//          Msg(TEXT("Failed to register filter graph with ROT! hr=0x%x"), hr);
//          g_dwGraphRegister = 0;
//     }
//#endif
     hr = mediaControl->Run();
     if (FAILED(hr))
     {
          this->MessageBox(L"mediaControl->Run()", L"MyVideoX", MB_OK | MB_ICONERROR);
          return;
     }
     playState = Running;
}

void MyVideoX::Window_App(Win::Event& e)
{
     if (mediaEventEx == NULL)
     {
          HRESULT hr;
          LONG code;
          LONG_PTR param1, param2;
          hr = mediaEventEx->GetEvent(&code, ¶m1, ¶m2, 0);
          if (SUCCEEDED(hr))
          {
               hr = mediaEventEx->FreeEventParams(code, param1, param2);
          }
     }
}

bool MyVideoX::GetFirstVideoDevice(IBaseFilterPtr& baseFilter)
{
     HRESULT hr;
     //_________________________________________________ 1. Create the ICreateDevEnumPtr
     ICreateDevEnumPtr createDevEnum = NULL;
     hr = createDevEnum.CreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER);
     if (FAILED(hr))
     {
          this->MessageBox(L"Unable to create ICreateDevEnumPtr", L"MyVideoX", MB_OK | MB_ICONERROR);
          return false;
     }
     IEnumMonikerPtr enumMoniker;
     //hr = createDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &enumMoniker, 0);
     hr = createDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enumMoniker, 0);
     if (SUCCEEDED(hr))
     {
          if (enumMoniker == NULL) return false;
          IMonikerPtr moniker = NULL;
          IPropertyBagPtr propertyBag = NULL;
          VARIANT var;
          VariantInit(&var);
          //_____________________________________________ 2. List Devices
          while (enumMoniker->Next(1, &moniker, NULL) == S_OK)
          {
               hr = moniker->BindToStorage(0, 0, IID_PPV_ARGS(&propertyBag));
               if (FAILED(hr))
               {
                    moniker = NULL;
                    continue;
               }
               hr = propertyBag->Read(L"Description", &var, 0);
               if (FAILED(hr))
               {
                    hr = propertyBag->Read(L"FriendlyName", &var, 0);
               }
               if (SUCCEEDED(hr))
               {
                    this->Text = var.bstrVal;
                    VariantClear(&var);
                    baseFilter = NULL;
                    hr = moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&baseFilter);
                    if (SUCCEEDED(hr))
                    {
                         hr = filterGraph->AddFilter(baseFilter, L"Capture Filter");
                         return true;
                    }
                    break;
               }
               moniker = NULL;
          }
     }
     return false;
}

void MyVideoX::Window_Size(Win::Event& e)
{
     ResizeVideoWindow();
}

void MyVideoX::Window_Close(Win::Event& e)
{
     this->Show(SW_HIDE);
     mediaControl->StopWhenReady();
     playState = Stopped;
     mediaEventEx->SetNotifyWindow(NULL, WM_APP, 0);
     if (videoWindow != NULL)
     {
          videoWindow->put_Visible(OAFALSE);
          videoWindow->put_Owner(NULL);
     }

#ifdef REGISTER_FILTERGRAPH
     // Remove filter graph from the running object table
     if (g_dwGraphRegister)
          RemoveGraphFromRot(g_dwGraphRegister);
#endif
     this->Destroy();
}

void MyVideoX::Window_WindosPosChanged(Win::Event& e)
{
     if (mediaControl == NULL) return;
     HRESULT hr = S_OK;
     if (IsIconic(hWnd) == FALSE)
     {
          if (playState != Running)
          {
               //_________________ 1. Start previewing video data
               hr = mediaControl->Run();
               playState = Running;
          }
     }
     else
     {
          //___________________ 2. Stop previewing video data
          hr = mediaControl->StopWhenReady();
          playState = Stopped;
     }
}

HRESULT MyVideoX::SetupVideoWindow()
{
     HRESULT hr;
     //_____________________________________ 1. Set the video window to be a child of the main window
     hr = videoWindow->put_Owner((OAHWND)hWnd);
     if (FAILED(hr)) return hr;

     //_____________________________________ 2. Set video window style
     hr = videoWindow->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
     if (FAILED(hr)) return hr;

     ResizeVideoWindow();
     hr = videoWindow->put_Visible(OATRUE);
     if (FAILED(hr)) return hr;
     return hr;
}

void MyVideoX::ResizeVideoWindow()
{
     if (videoWindow != NULL)
     {
          RECT rc;
          this->GetClientRect(rc);
          videoWindow->SetWindowPosition(0, 0, rc.right, rc.bottom);
     }
}

MyVideoXRun

© Copyright 2000-2021 Wintempla selo. All Rights Reserved. Jul 22 2021. Home