This concept is more special, meaning one of the videos, just like the poster we watch movies, is part of the movie. This is an image in the video file and then appears.
We are implemented through the interface provided by the Media Detector object, which is used inside the DirectShow editing service in the back.
Media Detector is a helpful object that can be obtained by format information from the media source file. It can also rush a BMP image from a video stream of a video file. If this file is available, you can get an image of this file.
Media Detector is not a filter, and the application does not need to use a filter graphic manager or create a filtration graphic. Inside the Media Detector, it creates a filter graphic that contains the Sample Grabber filter. In order to obtain
Graphics, Media Detector searches and pause filtrate graphics, then get a BMP image from the Sample Grabber filter. Applications and Media Detector communications are implemented via an iMediaDet interface. The operation of Media Detector has two modes. When you create it for the first time, it automatically enters information acquisition mode. You can specify the media file name to get information about each stream included in the file. This information includes file format, rate, or stream playback time, and the like. If the file contains a video stream, you can switch the Media Detector to the image rush mode, then you can get an image from the source file. Once you switch to the roller mode, you will not switch back to the original mode, which will be permanently loaded into the video stream. If you want it to work in other files, you have to create a new Media Detector instance.
Note: This example uses the ATL CCIMPTR class, which is a smart pointer and automatically counts. Because this you may not configure the header and other environments, there is a corresponding routine that can be performed in the CD. The routine will be combined and the merge is combined, and only one function is provided.
This roller process is taken into you a few steps:
a, win
Here implements a getBitmap function, which uses Media Detector to get. This function has taken the following steps:
1. Create Media Detector
Creating Media Detector can call CoCreateInstance. Such as:
CComptr
HR = pdet.cocreateinstance (__ uuidof (mediadet));
2, specify the media file
Specify the file name We use the iMediadet :: Put_FileName method. This method requires a BSTR parameter. This type is in the ATL.
HR = PDET-> PUT_FILENAME (BSTRFileName);
3. Detect information about each stream in the file. If there is a video stream, you get the size of the video.
Get the number of streams and then loop detect the type of each stream. IMEDIADET :: GET_OUTPUTSTREAMS method You can get the number of streams, and the iMediadet :: Put_CurrentStream method specifies the currently detected stream. After getting the first video stream, exit.
Long LSTREAMS;
Bool bfound = false;
HR = PDET-> Get_outputStreams (& LSTREAMS);
For (long i = 0; i { Guid Major_Type; HR = PDET-> PUT_CURRENTSTREAM (i); HR = PDET-> GET_STREAMTYPE (& Major_Type); if (Major_Type == MediaType_Video) // Find a video stream { Bfound = true; Break; } } If (! bfound) returnvfw_e_invalidimentiatype; If there is no video stream, the program exits. Inside the code, the iMediadet :: get_streamType method returns just a main type of GUID. This is a convenient practice if you don't need to detect a complete media type. In order to get the size of the video, we have to test the complete type. You can call the iMediadet :: get_streammediatype method to get subtypes, this method fills an AM_MEDIA_TYPE structure. Media Detector can use the VideoInfoHeader format parameters to convert all video into uncompressed formats. Long width = 0, height = 0; AM_MEDIA_TYPE MT; HR = PDET-> GET_STREAMMEDIATYPE (& MT); IF (mt.formattype == Format_VideoInfo) { VideoInfoHeader * PVIH = (VideoInfoHeader *) (mt.pbformat); Width = pvih-> bmiheader.biwidth; Height = pvih-> bmiheader.biheight; IF (HEIGHT <0) height * = -1; } Else { Return VFW_E_INVALIDMEDITYPE; FreeMediaType (MT); GET_STREAMMEDIATYPE method assigns a format block and is released after it is used. This example uses the FreeMediaType function to be released, this function is in the base library. 4, get images in the specified place Now we are ready to rush to the image. First call iMediadet :: getBitmapbits method, buffer parameters fill in NULL: Long lsize; HR = PDET-> GetBitmapBits (0, & lsize, null, width, height); This call returns the size of the buffer. The first parameter specifies the flow time of the positioning. This example is 0. We use the size of the video obtained earlier. If you specify other values Media Detector, it will be adjusted to the new size. If the call is successful, we call the getBitMapbit function again to assign buffers. En (ac)) { Char * pBuffer = new char [lsize]; IF (! pBuffer) Return E_OUTOFMEMORY; Try { HR = PDET-> GetBitmapBits (0, NULL, PBUFFER, WIDTH, HEIGHT); } Catch (...) { delete [] PBuffer; Return E_OUTOFMEMORY; } } Here is a complete code: HRESULT GETBITMAP (LPTSTSTSTSTSTSZZFILENAME, BITMAPINFOHEADER ** PPBMIH) { HRESULT HR; CComptr HR = pdet.cocreateinstance (__ uuidof (mediadet)); / / The conversion file is named BSTR type. CCOMBSTR BSTRFILENAME (PSZFileName); HR = PDET-> PUT_FILENAME (BSTRFileName); long Lstreams; Bool bfound = false; HR = PDET-> Get_outputStreams (& LSTREAMS); For (long i = 0; i { Guid Major_Type; HR = PDET-> PUT_CURRENTSTREAM (i); HR = PDET-> GET_STREAMTYPE (& Major_Type); IF (Major_Type == MediaType_Video) { Bfound = true; Break; } } If (! bfound) returnvfw_e_invalidimentiatype; Long width = 0, height = 0; AM_MEDIA_TYPE MT; HR = PDET-> GET_STREAMMEDIATYPE (& MT); IF (mt.formattype == Format_VideoInfo) { VideoInfoHeader * PVIH = (VideoInfoHeader *) (mt.pbformat); Width = pvih-> bmiheader.biwidth; Height = pvih-> bmiheader.biheight; IF (HEIGHT <0) height * = -1; } Else { Return VFW_E_INVALIDMEDITYPE; } FreeMediaType (MT); Long size; HR = PDET-> GetBitmapBits (0, & size, null, width, height); En (ac)) { Char * pBuffer = new char [size]; IF (! pBuffer) Return E_OUTOFMEMORY; Try { HR = PDET-> GetBitmapBits (0, NULL, PBUFFER, WIDTH, HEIGHT); } Catch (...) { delete [] PBuffer; Return E_OUTOFMEMORY; } En (ac)) { IF (* ppbmih) delete [] (* ppbmih); (* ppbmih) = (BitmapInfoHeader *) PBuffer; } } Return HR; } B, display image The final step is to draw images to the area we can see. We use the SetDibitStodevice function. The following example draws images to the client area: (drawn to the dialog in the example of this book) Case WM_Paint: { Paintstruct PS; HDC HDC = BeginPaint (HWND, & PS); IF (PBMI) { int result = setDibitstodevice (HDC, 0, 0, PBMI-> BIWIDTH, PBMI-> Biheight, 0, 0, 0, PBMI-> Biheight, PBuffer, Reinterpret_cast DIB_RGB_COLORS); } Endpaint (hwnd, & ps); } Break; The attached active code, you can refer to it, halo, it seems that you can't insert an accessory I put it into a function. Everyone can call it directly to PSZFileName is the file name (including path), and then call it in the main interface, you will be filled One of the video files, actually wants to see that, as long as it is positioned there, it is best MPEG1, and the other features I have not tried it. HRESULT GetBitmap (CString pszFileName) {CoInitialize (NULL); HRESULT hr; CComPtr