Visual C . Net DirectShow programming
Author: Time: April 14, 2004 15:28:51 Source: NEW YORK forum
DirectShow is a development package provided by Microsoft's streaming of streaming on the Windows platform, which is posted with the DirectX development package. DirectShow provides powerful support for multimedia capture and playback. Using DirectShow we can easily capture data from the acquisition card that supports the WDM drive model, and performs the corresponding post-processing or even stored in the file. It is widely supported in various media formats, including ASF, MPEG, AVI, DV, MP3, WAVE, etc., making the playback of multimedia data becomes light. In addition, DirectShow also integrates DirectX other parts (such as DirectDraw, DirectSound) technology, directly supporting DVD playback, nonlinear editing, and exchange with data cameras. What is more worth mentioning is that DirectShow provides an open development environment, we can customize your components according to your needs. This article will introduce DirectShow applications. Getting Started DirectShow uses a model called Filter Graph to manage the processing of the entire data stream, participating in the various functional modules of the data stream processing, said Filter, each Filter is connected in a certain order in a certain order in the Filter Graph, completing some Relatively independent features, such as Filter can complete some of the following features: Read files Get video streams from video devices to decode video streams to send data to sound cards or graphics cards with input and output, such as an MPEG-1 Decoding Filter It is the flow data encoded by MPEG, and its output is a decoded stream data. DirectShow is why different Filter is connected to complete specific features, we call these Filter's connection Filter Graph, as shown below, is a Filter Graph, which is played AVI:
Figure A Play AVI file Graph Filter chart on the map, each module represents different filters, media file files, read the AVI file from the hard disk, AVI separation FILTER separates files into audio streams and video streams, AVI decoding Filter pairs The stream is decoded and sent to the VIDEO performance FILTER, which is displayed by the latter on the display, and the default DirectSound device outputs the audio stream with DirectSound. Our applications do not need to manage this in this data stream, providing a Advanced component called the Filter Graph Manager in DirectShow. In our application, you only need to call its API, such as Run, STOP, etc. If you want to make further control over the data flow, you can access these Filter directly through the COM interface. Filter Graph Manager also provides another feature: the application can control how Filter Graph generates via manager.
Visual C . Net DirectShow Programming (2)
Author: Time: April 14, 2004 15:34:50 Source: NEW YORK forum
DirectShow Application From a broad sense, all DirectShow applications must complete three things, as shown below:
Figure B 1. Generate an instance of the Filter Graph Manager. 2. By using the Filter Grapth instance to generate Filter Graph, which Filter should consist of Filter Graph regarding our application needs. 3. Control by calling the Filter Graph Manager and the response Filter GRAPH and data stream from the Filter Graph's message. DirectShow is COM-based, Filter Graph Manager and Filter are COM objects, you should have a basic understanding of COM before starting to start. Let's start doing a simple DirectShow application, in which we implemented such a function: Open a media file and play it. Setting the environment Before using DirectShow, you must install DirectX's SDK, DirectX SDK can be downloaded on Microsoft's website. Currently, DirectX is 9.0. After installing DirectX SDK correctly, we must set the header file and library file of the DirectX SDK to make it within the Visual Studio search path. For Visual Studio .NET 2003, you can set up: Menu → Tools → Options → Item → VC Directory, add D: / DXSDK / INCLUDE in the included file, add D: / DXSDK / LIB (my SDK) in the library file The installation path is d: / dxsdk: header file
File Name Description DShow.h All DirectShow applications must contain library files
File Name Description Strmiids.lib This library file exports class ID (CLSID) and interface ID (IID), all DirectShow applications must contain this file. Quartz.lib This library file is exported to the function amgeTerRortext. If this function is called in your program, you must include this library file.
Visual C . Net DirectShow Programming (3)
Author: Time: April 14, 2004 15:39:58 Source: NEW YORK forum
Start Project Open Visual Studio .NET 2003, File → New → Item 1. Generate an MFC-based application, name PlayWnd.
2. Select the application type based on the dialog box, click Finish. 3. Set the engineering property item → PlayWnd Properties → Configuration Properties → Links → Enter → Additional Dependencies, Add Library Files Strmiids.lib and Quartz.lib. Since the dshow.h header file is used in any DirectShow project, we stdafx.h add to the following:
#include
IDC_STATIC control type Static TextCaption media file name: IDC_MEDIAFILE_EDIT control type Edit ControlIDC_BROWSE_BUTTON control type ButtonCaption browse IDC_VW_FRAME control type Picture ControlTypeRectangleIDC_PLAY_BUTTON control type ButtonCaption player IDC_PAUSE_BUTTON control type ButtonCaption pause IDCANCEL control type ButtonCaption closed 5.COM initialization and unloading, modify PlayWnd.cpp add Initialization code (the joined code is expressed in a thick black body, the same below)
Bool CPlayWndapp :: InitInstance () {// If a list of applications running on Windows XP specifies to use ComctL32.dll version 6 or higher to enable visual mode, you need initcommonControls (). Otherwise, the window will not be created. INITCOMMONCONTROLS (); // Initialization COM interface HRESULT HR = Coinitialize (NULL); "ERROR - COULD NOT IITIALIZE COM LIBRARY./N"); Return False;} cwinapp :: InitInstance ); AFXENABLECONTROLCONTAINER (); Modify PlayWnd.cpp Add Uninstall COM code, pay attention to the virtual function ExitInstance to overload int CPlayFileapp :: exitInstance () {// TOD Add a special code and / or call the base class // Close COM Couninitialize (); return cwinapp :: exitInstance ();
Visual C . Net DirectShow Programming (4)
Author: Time: April 14, 2004 15:41:24 Source: NEW YORK forum
6. Define media control member variables to modify PlayWnddlg.h as follows:
protected: HICON m_hIcon; // message mapping function generated virtual BOOL OnInitDialog (); afx_msg void OnSysCommand (UINT nID, LPARAM lParam); afx_msg void OnPaint (); afx_msg HCURSOR OnQueryDragIcon (); DECLARE_MESSAGE_MAP () // and associated media control the member variables private: IGraphBuilder * m_pGraph; // IGraphBuilder interface provides a method of generating phase // Filter Graph related IMediaControl * m_pMediaControl; // IMediaControl interface provides a method of controlling flow through the Filter Graph @ correlation data stream IMediaEventEx * m_pEvent; // iMediaeventEx inherits from iMediaEvent, providing method IMEDIASEEKING * m_pmediaseeking; // iMediaseeping provides a control stream playing location and play // speed method; // Current playback The name BOOL M_ISPLAYING; / / Current play status}; add initialization code in the constructor of CPLAYWNDDLG.
CPlayWndDlg :: CPlayWndDlg (CWnd * pParent / * = NULL * /): CDialog (CPlayWndDlg :: IDD, pParent) {m_hIcon = AfxGetApp () -> LoadIcon (IDR_MAINFRAME); m_pGraph = NULL; m_pMediaControl = NULL; m_pEvent = NULL; m_pmediaseeking = NULL; m_strmediafile = ""; m_isplaying = false;} Due to some of the initialization code related to forms, we must put it in CPLAYWNDDLG :: OnNitDialog (), we must be here Add WS_CLIPCHILDREN STYLE to CPLAYWNDDLG, because in our application, the video form is used as a child form of CPLAYWNDDLG, which is very important, and many developers are not using DirectShow just started using DirectShow. Set it correctly, causing the video that cannot be displayed correctly, the code is as follows: // Set the icon of this dialog. When the application main window is not a dialog, the framework will automatically / / perform this operation seticon (M_HICON, TRUE); // Set the big icon seticon (m_hicon, false); // Set the small icon // Tod Add additional Initialization code MODIFYSTYLE (0, WS_CLIPCHILDREN); (CEDIT *) getdlgitem (IDC_MEDIAFILE_EDIT) -> setReadOnly (TRUE); return true; // Unless the control is set, return TRUE} Add corresponding clear code, overload CPLAYWNDDLG's DestoryWindow method, as follows:
Bool cpplayWnddlg :: destroyWindow () {// TOD Add a special code and / or call the base class if (m_pgraph) m_pgraph-> release (); if (m_pmediacontrol) m_pmediacontrol-> release (); if (m_pevent) m_pevent- > Release (); if (m_pmediaseeking) m_pmediaseeking-> release (); m_pgraph = null; m_pmediacontrol = null; m_pevent = null; m_pmediaseeking = null; return cdialog :: destroyWindow ();
Visual C . Net DirectShow Programming (5)
Author: Time: April 14, 2004 15:42:47 Source: NEW YORK forum
7. Modify CPLAYWNDDLG: OONPAINT (), because the video display area must be redrawn by us ourselves:
Void CPLAYWNDLG :: OnPaint () {if (iSiconic ()) {cpaintdc DC (this); // Drawing device context sendMessage (WM_ICONERaseBkGnd, ReinterPret_cast
// Picture Control primary role is to control the control IDC_VW_FRAME Vedio Window display position void CPlayWndDlg :: MoveVideoWindow (void) {IVideoWindow * pVideoWinow = NULL; if (m_pGraph) {m_pGraph-> QueryInterface (IID_IVideoWindow, (void **) & pVideoWinow); CRECT RC; GETDLGITEM (IDC_VW_FRAME) -> getWindowRect (RC); ScreenToClient (RC); pvideoWinow-> setWindowPosition (rc.left, rc.top, rc.width (), rc.Height ()); pvideoWinow-> Release ); pVideoWinow = NULL;}} void CPlayWndDlg :: CleanUp (void) {long levCode; IVideoWindow * pVidWin = NULL;! if (m_pGraph) return; m_pGraph-> QueryInterface (IID_IVideoWindow, (void **) & pVidWin); m_pEvent- > WaitForCompletion (INFINITE, & levCode); pVidWin-> put_Visible (OAFALSE); pVidWin-> Release (); m_pMediaSeeking-> Release (); m_pMediaControl-> Release (); m_pEvent-> Release (); m_pGraph-> Release () ; m_pMediaSeeking = NULL; m_pMediaControl = NULL; m_pEvent = NULL; m_pGraph = NULL; UpdateData (FALSE); CClientDC dc (GetDlgItem (IDC_VW_FRAME)); dc.SetBkColor (RGB (0,0,0)); CRect rc; GetDlgItem ( IDC_VW_FRAME) -> getClientRect (RC); C lientToScreen (rc); dc.FillRect (rc, CBrush :: FromHandle ((HBRUSH) GetStockObject (BLACK_BRUSH))); Invalidate ();} BOOL CPlayWndDlg :: Stop (void) {IVideoWindow * pVidWin = NULL; HRESULT hr; if (m_pMediaControl) {LONGLONG pos = 0; hr = m_pMediaControl-> Stop (); hr = m_pMediaSeeking-> SetPositions (& pos, AM_SEEKING_AbsolutePositioning, & pos, AM_SEEKING_NoPositioning); m_pGraph-> QueryInterface (IID_IVideoWindow, (void **) & pVidWin); pVidWin -> put_Visible (OAFALSE); m_isPlaying = FALSE; GetDlgItem (IDC_PLAY_BUTTON) -> EnableWindow (TRUE); GetDlgItem (IDC_PAUSE_BUTTON) -> EnableWindow (FALSE); pVidWin-> Release (); long levCode;
m_pEvent-> WaitForCompletion (INFINITE, & levCode); m_pMediaControl-> Release (); return TRUE;} return FALSE;} BOOL CPlayWndDlg :: Play (void) {// Run IVideoWindow * pVidWin = NULL; if (m_pGraph) {m_pGraph- > QueryInterface (IID_IVideoWindow, (void **) & pVidWin); pVidWin-> put_Visible (OATRUE); m_pGraph-> QueryInterface (IID_IMediaControl, (void **) & m_pMediaControl); m_pMediaControl-> Run (); m_isPlaying = TRUE; GetDlgItem (IDC_PLAY_BUTTON ) -> EnableWindow (false); getdlgitem (idc_pause_button) -> enableWindow; Return true;} Return False; Net DirectShow Programming (6)
Author: Time: April 14, 2004 15:44:01 Source: NEW YORK forum
Browse, play, pause, close the four-button corresponding event response function is as follows:
void CPlayWndDlg :: OnBnClickedBrowseButton () {CFileDialog dlgFile (TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Movie Files (* .avi; * mpg;.. * mpeg) | / * .avi;.. * mpg; * mpeg | / Audio files (* .wav; * mp3; *. Mpa; *. Mpu; *. Au) | / * .wav; *. Mp3; *. MPA; *. Mpu; *. Au | / midi files * .MID; *. MIDI; *. RMI) | / * .mid; *. midi; *. RMI | | ", this); if (dlgfile.domodal () == idok) {m_strmediafile = DLGFILE.GETPATHNAME ); GetDlgItem (IDC_MEDIAFILE_EDIT) -> SetWindowText (m_strMediaFile);} else return; CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **) & m_pGraph); HRESULT hr = m_pGraph-> RenderFile (CA2W (m_strMediaFile), NULL) ; If (HR)) {char SZMSG [200]; AMGETERRORTEXT (HR, SZMSG, SIZEOF (SZMSG)); AFXMESSAGEBOX (SZMSG);} // Specify parent form iVideoWindow * pvidwin = null; m_pgraph-> queryinterface IID_IVideoWindow, (void **) & pVidWin); pVidWin-> put_Owner ((OAHWND) m_hWnd); pVidWin-> put_WindowStyle (WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); CRect rc; GetDlgItem (IDC_VW_FRAME) -> GetWindowRe CT (RC); ScreenToClient (rc); pvidwin-> setWindowPosition (rc.left, rc.top, rc.width (), rc.Height ()); // Note The event of Filter Graph Manager is issued in WM_GRAPHNOTIFY ( user-defined message) m_pGraph-> QueryInterface (IID_IMediaEventEx, (void **) & m_pEvent);. m_pEvent-> SetNotifyWindow ((OAHWND) m_hWnd, WM_GRAPHNOTIFY, 0); // set Seeking m_pGraph-> QueryInterface (IID_IMediaSeeking, (void * *) & m_pMediaSeeking);} void CPlayWndDlg :: OnBnClickedPlayButton () {Play ();} void CPlayWndDlg :: OnBnClickedPauseButton () {m_pMediaControl-> Pause (); m_isPlaying = TRUE; GetDlgItem (IDC_PLAY_BUTTON) -> EnableWindow (TRUE); GetDlgItem (Idc_pause_button) -> EnableWindow (FALSE);
} void cpplayWnddlg :: OnBnclicKedCancel () {// TOD Add control notification handler code CLEANUP (); oncancel ();} 8. Add a message to the WM_GraphNotify message, and its response function Add message ID definition in playwnddlg: #define wm_graphNotify WM_USER 101 In PlayWnddlg.h, the code is as follows:
@ Achieve protected: HICON m_hIcon; // message mapping function generated virtual BOOL OnInitDialog (); afx_msg void OnSysCommand (UINT nID, LPARAM lParam); afx_msg void OnPaint (); afx_msg HCURSOR OnQueryDragIcon (); DECLARE_MESSAGE_MAP () afx_msg HRESULT OnGraphNotify (WPARAM WPARAM, LPARAM LPARAM); Private: IGraphbuilder * m_pgraph; iMediaControl * m_pmediaeventrol; iMediaEventEx * m_pevent; playwnddlg.cpp, as follows:
ON_BN_CLICKED (IDC_BROWSE_BUTTON, OnBnClickedBrowseButton) ON_BN_CLICKED (IDC_PLAY_BUTTON, OnBnClickedPlayButton) ON_BN_CLICKED (IDC_PAUSE_BUTTON, OnBnClickedPauseButton) ON_BN_CLICKED (IDCANCEL, OnBnClickedCancel) ON_MESSAGE (WM_GRAPHNOTIFY, OnGraphNotify) END_MESSAGE_MAP () to achieve the following:
HRESULT CPlayWndDlg :: OnGraphNotify (WPARAM wParam, LPARAM lParam) {long levCode, lparam1, lparam2; HRESULT hr; while (hr = m_pEvent-> GetEvent (& levCode, & lparam1, & lparam2, 0), SUCCEEDED (hr)) {hr = m_pEvent -> FreeEventParams (Levcode, LPARAM1, LPARAM2); if ((EC_COMPLETE == Levcode) || (EC_USERABORT == Levcode)) {trace ("End of the Media File !! ./ n"); stop (); / / Clean;}} Return HR;