locked
Sequencer Source 2nd segment: MESessionTopologySet, with status C00D5214 : sound but no image RRS feed

  • Question

  • I am working on an adpated version of the audio playlist sample in the SDK but using video clips instead that are fed in at winmain.cpp :

    g_pPlayer->AddToPlaylist(L"E:\\renderTests\\WMV\\steer_clear.wmv");
    g_pPlayer->AddToPlaylist(L"E:\\renderTests\\WMV\\food+conversation.wmv");
    g_pPlayer->AddToPlaylist(L"E:\\renderTests\\WMV\\bread+cheese.wmv");

     g_pPlayer->StartPlayback();

    The first segment plays fine but then all the subsequent segments play without the image but with the sound still playing. There is an error code is from the hrStatus value in the line

    hr = pEvent->GetStatus(&hrStatus);

    from the Invoke function.

    Looking up the error codes it states:

     0xC00D5214 , _T("Unsupported operations in topoloader"), _T("MF_E_TOPO_UNSUPPORTED")},

    I find this odd as it appears that the topology has been successfully built in the AddSegment function called from AddToPlaylist function. Also if I change the order of clips fed in, the first clip that formerly played fine gives the same error. Perhaps I need to add some code to the MESessionTopologySet switch statement in the Invoke(IMFAsyncResult *pAsyncResult) function which is currently empty. But I am not sure, any ideas anyone?:

     

    HRESULT myPlayer::Invoke(IMFAsyncResult *pResult)
    {
        HRESULT hr = S_OK;
        IMFMediaEvent* pEvent = NULL;
        MediaEventType meType = MEUnknown;  // Event type
        HRESULT hrStatus = S_OK;            // Event status
        PROPVARIANT eventData;                  // Event data

        MF_TOPOSTATUS TopoStatus = MF_TOPOSTATUS_INVALID; // Used with MESessionTopologyStatus event. 
        PropVariantInit(&eventData);

        // Get the event from the event queue.
        hr = m_pSession->EndGetEvent(pResult, &pEvent);
        LOG_IF_FAILED(L"IMediaEventGenerator::EndGetEvent", hr);

        // Get the event type.
        if (SUCCEEDED(hr))
        {
            hr = pEvent->GetType(&meType);
            LOG_IF_FAILED(L"IMFMediaEvent::GetType", hr);
        }

        if (SUCCEEDED(hr))
        {
            // Get the event data
            hr = pEvent->GetValue(&eventData);
            LOG_IF_FAILED(L"IMFMediaEvent::GetValue", hr);

        }

        // Get the event status. If the operation that triggered the event did
        // not succeed, the status is a failure code.
        if (SUCCEEDED(hr))
        {
            hr = pEvent->GetStatus(&hrStatus); ////////FAILS HERE on second MESessionTopologySet event but not on others ////////
          
        }

        if (SUCCEEDED(hr))
        {
            TRACE((L"Media event: %s, with status %X", EventName(meType),hrStatus));

            // Check if the async operation succeeded.
            if (SUCCEEDED(hrStatus))
            {
                // Switch on the event type. Update the internal state of the CPlayer as needed.
                switch(meType)
                {
                case MESessionTopologyStatus:
                    {
                        TRACE((L"%d: MESessionTopologyStatus, Status: 0x%X", meType, hrStatus ));
                       
                        UINT value = 0;
                       
                        hr = pEvent->GetUINT32(MF_EVENT_TOPOLOGY_STATUS, &value);
                        MFSequencerElementId SegmentID = 0;
                        TOPOID ID;
                       
                        //Get information about the new segment
                        IMFTopology *pTopology = NULL;
                       
                        hr = eventData.punkVal->QueryInterface(__uuidof(IMFTopology),(void**)&pTopology);

                        if (SUCCEEDED(hr))
                        {
                            pTopology->GetTopologyID(&ID);
                        }
                        if (SUCCEEDED(hr))
                        {
                            m_SegmentList.GetSegmentIDByTopoID(ID, &SegmentID);
                        }
                       
                        topostat.iTopologyStatusType = value;
                        topostat.iSegmentId = SegmentID;

                        switch(value)
                        {
                        case MF_TOPOSTATUS_STARTED_SOURCE:
                                m_ActiveSegment = SegmentID;
                                break;
                           
                            case MF_TOPOSTATUS_ENDED:
                                m_ActiveSegment = 0;
                                break;

                        }
                   
                        PostMessage(m_hwndVideoApp, WM_APP_NOTIFY, MESessionTopologyStatus, (LPARAM)&topostat);
                       
                        SAFE_RELEASE(pTopology);

                        break;
                        }
                     case MENewPresentation:
                    {
                        TRACE((L"%d: MENewPresentation, Status: 0x%X", meType, hrStatus ));

                        IMFPresentationDescriptor *pPresentationDescriptor = NULL;

                        MFSequencerElementId SegmentId = 0;
                       
                        hr = eventData.punkVal->QueryInterface(
                                __uuidof(IMFPresentationDescriptor),
                                (void**)&pPresentationDescriptor); 

                        if (SUCCEEDED(hr))
                        {
                            //Queue the next segment on the media session
                            this->QueueNextSegment(pPresentationDescriptor, &SegmentId);
                        }

                        SAFE_RELEASE(pPresentationDescriptor);

                        PostMessage(m_hwndVideoApp, WM_APP_NOTIFY, meType, SegmentId);
       
                        break;
                    }
                case MESessionNotifyPresentationTime:
                    {
                        TRACE((L"%d:  MESessionNotifyPresentationTime, Status: 0x%X", meType, hrStatus ));//));//

                        hr = HandleNotifyPresentationTime( pEvent );
                        break;
                    }
                case MESessionStarted:
                   hr = OnSessionStarted(pEvent);
                    break;

                case MESessionPaused:
                    hr = OnSessionPaused(pEvent);
                    break;

                case MESessionClosed:
                  //  hr = OnSessionClosed(pEvent);
                    break;

                case MEEndOfPresentation:
                    hr = OnPresentationEnded(pEvent);
                    break;
                case MESessionTopologySet:
                   //nothing here as yet. Should there be?
                 break;
                }

            }
           else
            {
                //TRACE((L"notifyError"
                // The async operation failed. Notify the application
                NotifyError(hrStatus);
            }
        }

        // Request another event.
        if (meType != MESessionClosed)
        {
            hr = m_pSession->BeginGetEvent(this, NULL);
            //LOG_IF_OK(L"IMFMediaSession::BeginGetEvent", hr);
        }

        SAFE_RELEASE(pEvent);
        // Clean up.
        PropVariantClear(&eventData);

        return hr;
    }

     

     Is it possible and more advisable (as I want dxva2) to append a full as opposed to partial topology to the sequencer source?  Perhaps this would circumvent the topoplgy loader being unable to resolve the current toplogies after the first one is set.  I am on Vista 32 bit btw using Visual C++ 2005 Express Edition.  Any help much appreciated.

     

    Monday, May 24, 2010 9:56 AM

Answers

  • Adding topologies to the sequencer does not do any topology validation or resolution.  If there is a problem with the topology, you will not get an error until you call IMFMediaSession::SetTopology, when the media session will actually try to resolve the topology.  The MF_E_TOPO_UNSUPPORTED error typically indicates a topology with inconsistent structure -- outputs that lead to nowhere, source nodes in the middle of the topology, or other unresolvable situations.

    How are you setting up the video renderer?  Are you trying to reuse the same output node across topologies?  I could see this situation happening if you reused the node -- connecting the reused node in the third topology would disconnect the node in the second topology, whereas the first topology had already been resolved on the session.  In that case, creating a clone (IMFTopologyNode::CloneFrom) node instead of reusing the same node would fix the problem.

    Using a partial topology is generally the right way to go.  The topology loader will take care of using the right decoder, setting the right media types, and setting up DXVA, all of which can be quite tricky. 

    Tuesday, June 1, 2010 11:01 PM