Elecard
May 22, 2013, 06:55:55 pm *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: A question for DirectShow programmers  (Read 17671 times)
PimpDaddy
Newbie
*
Posts: 1


View Profile
« on: January 15, 2006, 02:13:45 am »

Hi, I m writing an app that takes a video file as input and extract a frame with a given number from it. I didn't come up with anything original, I just took the GrabBitmaps sample and made some modifications: I added a call pMediaSeeking->SetTimeFormat( &TIME_FORMAT_FRAME ). It works perfectly well for mpg, and avi files. BUT!!! When I feed it an ".wmv" file, it refuses to work. It even writes a really strange line to the console output: "quicktime_open: error in header". I m wondering what does quicktime have to do with Windows Media.
I ve installed MediaFormat SDK, so RenderFile() works just fine on WMV's. the problem emerges when I try to connecs an AsyncReader's output to the SampleGrabber's input.  HRESULT = 0x80040217 8 - (


Code:

int GrabBitmaps(TCHAR * szFile )
{
    USES_CONVERSION;
    CComPtr< ISampleGrabber > pGrabber;
    CComPtr< IBaseFilter >    pSource;
    CComPtr< IGraphBuilder >  pGraph;
    CComPtr< IVideoWindow >   pVideoWindow;
    HRESULT hr;

    // Create the sample grabber
    pGrabber.CoCreateInstance( CLSID_SampleGrabber );
    if( !pGrabber ) { _tprintf( TEXT("Could not create CLSID_SampleGrabber\r\n") ); return -1; }
   
    CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase( pGrabber );

    // Create the file reader
    pSource.CoCreateInstance( CLSID_AsyncReader );
    if( !pSource ) { _tprintf( TEXT("Could not create source filter\r\n") ); return -1; }

    // Create the graph
    pGraph.CoCreateInstance( CLSID_FilterGraph );
    if( !pGraph ) { _tprintf( TEXT("Could not not create the graph\r\n") ); return -1; }

    // Put them in the graph
    hr = pGraph->AddFilter( pSource, L"Source" );
    hr = pGraph->AddFilter( pGrabberBase, L"Grabber" );

    // Load the source
    CComQIPtr< IFileSourceFilter, &IID_IFileSourceFilter > pLoad( pSource );
    hr = pLoad->Load( T2W( szFile ), NULL );
    if( FAILED( hr ) ) { _tprintf( TEXT("Could not load the media file\r\n") ); return -1; }

    // Tell the grabber to grab 24-bit video. Must do this
    // before connecting it
    CMediaType GrabType;
    GrabType.SetType( &MEDIATYPE_Video );
    GrabType.SetSubtype( &MEDIASUBTYPE_RGB24 );
    hr = pGrabber->SetMediaType( &GrabType );

    // Get the output pin and the input pin
    CComPtr< IPin > pSourcePin;
    CComPtr< IPin > pGrabPin;

    pSourcePin = GetOutPin( pSource, 0 );
    pGrabPin   = GetInPin( pGrabberBase, 0 );
    // ... and connect them
    hr = pGraph->Connect( pSourcePin, pGrabPin ); /* !!!! ##___PROBLEM HERE___## !!!!  */
    if( FAILED( hr ) ) { _tprintf( TEXT("Could not connect source filter to grabber\r\n") ); return -1; }

    // This semi-COM object will receive sample callbacks for us
    CSampleGrabberCB CB;

    // Ask for the connection media type so we know its size
    AM_MEDIA_TYPE mt;
    hr = pGrabber->GetConnectedMediaType( &mt );

    VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
    CB.Width  = vih->bmiHeader.biWidth;
    CB.Height = vih->bmiHeader.biHeight;
    FreeMediaType( mt );

    // Render the grabber output pin (to a video renderer)
    CComPtr <IPin> pGrabOutPin = GetOutPin( pGrabberBase, 0 );
    hr = pGraph->Render( pGrabOutPin );
    if( FAILED( hr ) ) { _tprintf( TEXT("Could not render grabber output pin\r\n") ); return -1; }

    // Don't buffer the samples as they pass through
    hr = pGrabber->SetBufferSamples( FALSE );

    // Only grab one at a time, stop stream after
    // grabbing one sample
    hr = pGrabber->SetOneShot( TRUE );

    // Set the callback, so we can grab the one sample
    hr = pGrabber->SetCallback( &CB, 1 );

    // Get the seeking interface, so we can seek to a location
    CComQIPtr< IMediaSeeking, &IID_IMediaSeeking > pSeeking( pGraph );

    hr = pSeeking->IsFormatSupported( &TIME_FORMAT_FRAME );
    if ( hr != S_OK ) return 1;
    pSeeking->SetTimeFormat( &TIME_FORMAT_FRAME );

    // Query the graph for the IVideoWindow interface and use it to
    // disable AutoShow.  This will prevent the ActiveMovie window from
    // being displayed while we grab bitmaps from the running movie.
    CComQIPtr< IVideoWindow, &IID_IVideoWindow > pWindow = pGraph;
    if (pWindow) { hr = pWindow->put_AutoShow(OAFALSE); }

    // set position
    REFERENCE_TIME Start = 10;
    hr = pSeeking->SetPositions( &Start, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning );

    // activate the threads
    CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
    hr = pControl->Run( );

    // wait for the graph to settle
    CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
    long EvCode = 0;

    hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
   
    // callback wrote the sample
    _tprintf(TEXT("Sample grabbing complete.\r\n"));
    return 0;
}

Logged

verything that doesn't kill me makes me stronger.
-- some wise guy
posdnya
Newbie
*
Posts: 75


View Profile WWW
« Reply #1 on: January 17, 2006, 08:39:48 am »

Render the wmv file in graph editor and you'll see, that AsyncReader is not used there, but the special filter which is source and wmv demuxer at once.
You may either call this filter by its guid, or render wmv file in your app, then kill video renderer and put there your grab bitmap filter instead.
Logged
Dmitry Vergeles
Newbie
*
Posts: 216


View Profile WWW
« Reply #2 on: January 18, 2006, 01:19:55 am »

Quote from: "PimpDaddy"
Hi, I m writing an app that takes a video file as input and extract a frame with a given number from it. I didn't come up with anything original, I just took the GrabBitmaps sample and made some modifications: I added a call pMediaSeeking->SetTimeFormat( &TIME_FORMAT_FRAME ). It works perfectly well for mpg, and avi files. BUT!!! When I feed it an ".wmv" file, it refuses to work. It even writes a really strange line to the console output: "quicktime_open: error in header". I m wondering what does quicktime have to do with Windows Media.
I ve installed MediaFormat SDK, so RenderFile() works just fine on WMV's. the problem emerges when I try to connecs an AsyncReader's output to the SampleGrabber's input.  HRESULT = 0x80040217 8 - (



Really, all you need is to make use of IMediaDet Interface.
Just take a look at this:
http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/htm/imediadetinterface.asp
Logged

egards,
Dmitry Vergeles
Solveig Multimedia
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!