locked
Capture a Photo from Webcam Still Pin using MFSourceReader? RRS feed

  • Question

  • Hi,

      I am developing a webcam app with Media Foundation technology, by reference of the MFCaptureToFile sample (http://msdn.microsoft.com/en-us/library/windows/desktop/ee663604(v=vs.85).aspx). The MFSourceReader solution works fine for the preview & capture pins. However, I encounter a problem to capture a photo from the still pin. After the ReadSample command, I receive no sample from the still pin (only one callback with NULL sample and MF_SOURCE_READERF_STREAMTICK flag, and no more callback anymore).

      From my DShow experience, I have to issue the IAMVideoControl::SetMode (IPin *pPin, long Mode) command with VideoControlFlag_Trigger flag to trigger the still pin. I wonder is there any corresponding command for MF?

      I notice that the webcam MediaSource object does support the IAMVideoControl interface, but I cannot get an IPin pointer to make it work.

      Can anyone give me some suggestions or help?

    Thank you.

    Monday, December 10, 2012 10:29 AM

All replies

  • I found a attribute for Windows 8, "MF_DEVICESTREAM_TAKEPHOTO_TRIGGER", and set it to the Still image stream. But still get the same result:  NULL IMFSample  and MF_SOURCE_READERF_STREAMTICK flag.

    Then, I try to set the "MF_DEVICESTREAM_TAKEPHOTO_TRIGGER" attribute when calling MFCreateSourceReaderFromMediaSource( ), but still no lock.

    The following is my code segment

     

    if (SUCCEEDED(hr)) hr = MFCreateAttributes(&pAttributes, 2); if (SUCCEEDED(hr)) hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, TRUE); if (SUCCEEDED(hr)) hr = pAttributes->SetUINT32(MF_DEVICESTREAM_TAKEPHOTO_TRIGGER , 1); if (SUCCEEDED(hr)) hr = MFCreateSourceReaderFromMediaSource(pSource, pAttributes, &m_pReader); //select still image stream if (SUCCEEDED(hr)) { hr = m_pReader->SetStreamSelection(STILL_STREAM_ID, TRUE); } if (SUCCEEDED(hr)) { hr = m_pReader->GetNativeMediaType(STILL_STREAM_ID, 0, &pType); hr = m_pReader->SetCurrentMediaType(STILL_STREAM_ID, NULL, pType ); } //trigger take-photo command if (SUCCEEDED(hr)) hr = pstream->SetUINT32(MF_DEVICESTREAM_TAKEPHOTO_TRIGGER , 1); // Ask for the still image frame using synchronous call if (SUCCEEDED(hr)) { IMFSample *pSample = NULL; DWORD dwStreamFlags = 0; DWORD dwActualStreamIndex = 0; LONGLONG Timestamp; //MF_SOURCE_READER_FIRST_VIDEO_STREAM; STILL_STREAM_ID hr = m_pReader->ReadSample((DWORD)STILL_STREAM_ID, 0, &dwActualStreamIndex, &dwStreamFlags, // MF_SOURCE_READERF_STREAMTICK (256); MF_SOURCE_READERF_ERROR (1) &Timestamp, &pSample); //TODO: save the sample data } //deselect still stream if(m_pReader) hr = m_pReader->SetStreamSelection(STILL_STREAM_ID, FALSE);

     


    Thursday, January 24, 2013 1:33 AM
  • Hi Jim,

      Thank you for the update.

      In you code segment,

        //trigger take-photo command
        if (SUCCEEDED(hr)) hr = pstream->SetUINT32(MF_DEVICESTREAM_TAKEPHOTO_TRIGGER , 1);

      Is the "pstream" pointer an IMFMediaStream instance? If Yes, can you share how do you get it.
     

      I tried IMFAsyncCallback for listening the MENewStream event from MediaSource, but it could not work with SourceReader. SourceReader seems already listening to the events of the MediaSource, and it does not handle MENewStream event.

    Thursday, January 24, 2013 9:54 AM
  • The following is the code to get pstream:

    IMFStreamDescriptor *pstream = NULL;
    IMFPresentationDescriptor *pPrds = NULL;
    IMFMediaSource  *pSource = NULL;

    ....

    hr = pActivate->ActivateObject(__uuidof(IMFMediaSource),(void**)&pSource);
    hr = pSource->CreatePresentationDescriptor(&pPrds);
    hr = pPrds->GetStreamDescriptorByIndex(STILL_STREAM_ID, &issel01, &pstream);

    Monday, January 28, 2013 9:45 AM
  • Hi Jim,

      Thank you for the information. So, it is an IMFStreamDescriptor instance, instead of an IMFMediaStream instance.

      From your previous post, I guess that the MF_DEVICESTREAM_TAKEPHOTO_TRIGGER attribute is for the stream according to its naming. However, I have no idea about how to use it. I ever thought about setting this attribute to the IMFMediaStream instance, but I could not get the instance.

     

    Monday, January 28, 2013 10:30 AM
  • Jay:

    I do'nt think you can set the attribute, MF_DEVICESTREAM_TAKEPHOTO_TRIGGER attribute, to  IMFMediaStream interface, since it is not inherits from IMFAttributes interface.

    For this topic, I even asked Microsoft Technical support, but still did not get any solid solution. 

     

    Thursday, January 31, 2013 7:12 AM