Using DirectShow in C ++ to Decode MP4 Video with H.264 Stream

I have an MP4 video containing one H.264 stream and an audio stream. I would like to use DirectShow with C ++ to decode a video, but I am having trouble setting up DirectShow filters and hope someone can help?

Here's my setup code for using DirectShow to decode a WMV3 stream, which I work well:

hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGraph);

if (SUCCEEDED(hr))      hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&m_pFilter);
if (SUCCEEDED(hr))      hr = m_pFilter->QueryInterface(IID_IVMRFilterConfig9, reinterpret_cast<void**>(&filterConfig));
if (SUCCEEDED(hr))      hr = filterConfig->SetRenderingMode( VMR9Mode_Renderless );
if (SUCCEEDED(hr))      hr = filterConfig->SetNumberOfStreams(2);
if (SUCCEEDED(hr))      hr = SetAllocatorPresenter( m_pFilter, g_pMainWindow );
if (SUCCEEDED(hr))      hr = m_pGraph->AddFilter(m_pFilter, L"Video Mixing Renderer 9");
if (SUCCEEDED(hr))      hr = m_pGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&m_pMediaControl));
if (SUCCEEDED(hr))      hr = m_pGraph->QueryInterface(IID_IBasicAudio, reinterpret_cast<void**>(&m_pBasicAudio));
if (SUCCEEDED(hr))      hr = m_pGraph->RenderFile( lpFilename, NULL );

      

I can't figure out the correct setting for MP4 decoding. I already installed 3ivx and ffdshow as found in other posts and now GraphEdit can open my file and display the correct plots (thought - I'm on a 64-bit machine, and when I run the 64-bit version of GraphEdit it's DOESN, but 32 -bit ... could it have something to do with it?) VLC can play my videos perfectly.

I have searched the ENTIRE internet for examples specific to this and cannot find them.

My video file format looks like this (ffmpeg output):

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42mp41
    creation_time   : 2013-01-16 19:14:52
  Duration: 00:05:25.62, start: 0.033367, bitrate: 3396 kb/s
    Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 3393 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc
    Metadata:
      creation_time   : 2013-01-16 19:14:52
      handler_name    : ?Mainconcept Video Media Handler

      

Any help would be greatly appreciated!

Regards, Graham

+3


source to share


1 answer


There is no default default MP4 demuxer in Windows, so you need to set one of them in Advanced DirectShow to cover MP4.

  • you need a demultiplexer of correct bitness (32 vs 64 bit) set to match the bit of your code / application (or GraphEdit)
  • VLC doesn't matter as it has its own demultiplexer built into
  • you also need an H.264 decoder and you seem to already have


Your code is correct, but this graph construction method is not entirely realistic. First of all, you need to find out if you have any useful error code (you might have a call RenderFile

).

If GraphEdit Win32 runs on this system, all required components (filters) should be available. The difference is that GraphEdit doesn't create the graph the way you do. Instead, it uses a IGraphBuilder::AddSourceFilter

starter filter for the given file to add and then displays its contacts. If you take the same approach and in the last step you add your VMR filter for the video presentation, this will work well.

0


source







All Articles