HRESULT MfMediaStream::WaitForStreamEvent(MediaEventType event_type) { expected_event_ = event_type; HRESULT hr = ptr_stream_->BeginGetEvent(this, NULL); if (FAILED(hr)) { DBGLOG("ERROR, BeginGetEvent failed" << HRLOG(hr)); return hr; } hr = stream_event_.Wait(); if (FAILED(hr)) { DBGLOG("ERROR, stream event wait failed" << HRLOG(hr)); return hr; } if (FAILED(stream_event_error_)) { // when event handling fails the last error is stored in // |media_event_type_recvd_|, just return it to the caller DBGLOG("ERROR, stream event handling failed" << HRLOG(stream_event_error_)); return stream_event_error_; } return hr; }
HRESULT MfMediaStream::Create_(IMFMediaStreamPtr& ptr_stream) { ptr_stream_ = ptr_stream; HRESULT hr = ptr_stream_->QueryInterface(IID_IMFMediaEventGenerator, reinterpret_cast<void**>(&ptr_event_queue_)); if (FAILED(hr)) { DBGLOG("ERROR, failed to obtain stream event generator" << HRLOG(hr) << " returning E_FAIL."); return E_FAIL; } IMFStreamDescriptorPtr ptr_desc; hr = ptr_stream->GetStreamDescriptor(&ptr_desc); if (FAILED(hr)) { DBGLOG("ERROR, GetStreamDescriptor failed" << HRLOG(hr)); return hr; } hr = get_media_type(ptr_desc, &ptr_media_type_); if (FAILED(hr)) { DBGLOG("ERROR, get_media_type failed" << HRLOG(hr)); return hr; } hr = stream_event_.Create(); if (FAILED(hr)) { DBGLOG("ERROR, stream event creation failed" << HRLOG(hr)); return hr; } return hr; }
HRESULT ComDllWrapper::LoadDll_() { dll_module_ = LoadLibrary(dll_path_.c_str()); if (dll_module_) { ptrfn_get_class_object_ = reinterpret_cast<DllGetClassObjFunc>( GetProcAddress(dll_module_, "DllGetClassObject")); } HRESULT hr = E_FAIL; if (dll_module_ && ptrfn_get_class_object_) { hr = ptrfn_get_class_object_(clsid_, IID_IClassFactory, reinterpret_cast<void**>(&ptr_class_factory_)); if (FAILED(hr)) { DBGLOG("DllGetClassObject failed" << HRLOG(hr)); } //if (SUCCEEDED(hr) && ptr_class_factory_) //{ // hr = ptr_class_factory_->LockServer(TRUE); // if (FAILED(hr)) // { // DBGLOG("LockServer failed" << HRLOG(hr)); // return hr; // } //} } return hr; }
HRESULT MfMediaStream::GetSample(IMFSample **ptr_sample) { if (!ptr_stream_) { DBGLOG("ERROR, stream not set, E_UNEXPECTED"); return E_UNEXPECTED; } // TODO(tomfinegan): need to handle pause; RequestSample will succeed while // paused, but the stream won't deliver the sample. // This means we'll block in |WaitForStreamEvent|...? // Curse you for not being specific MSDN. I guess I have // to return a wrong state error when paused to avoid the // situation altogether. HRESULT hr = ptr_stream_->RequestSample(NULL); // MF_E_MEDIA_SOURCE_WRONGSTATE is not treated as an error by the pipeline if (FAILED(hr)) { DBGLOG("ERROR, RequestSample failed" << HRLOG(hr)); return hr; } hr = WaitForStreamEvent(MEMediaSample); if (FAILED(hr)) { DBGLOG("WaitForStreamEvent MEMediaSample failed" << HRLOG(hr)); return hr; } if (FAILED(stream_event_error_)) { DBGLOG("MEMediaSample event handling failed" << HRLOG(stream_event_error_)); return stream_event_error_; } if (!ptr_sample_) { // TODO(tomfinegan): DBGLOG("ERROR, null sample"); return E_OUTOFMEMORY; } *ptr_sample = ptr_sample_.Detach(); return hr; }
HRESULT MfMediaStream::OnMediaSample_(IMFMediaEventPtr& ptr_event) { IUnknownPtr ptr_iunk; HRESULT hr = get_event_iunk_ptr(ptr_event, &ptr_iunk); if (FAILED(hr)) { DBGLOG("ERROR, could not obtain IUnknown from event" << HRLOG(hr)); return hr; } ptr_sample_ = ptr_iunk; if (!ptr_sample_) { DBGLOG("ERROR, sample pointer null"); return E_POINTER; } return S_OK; }
HRESULT MfMediaStream::Create(IMFMediaStreamPtr& ptr_mfstream, MfMediaStream** ptr_instance) { if (!ptr_mfstream) { DBGLOG("null IMFMediaStream, returning E_INVALIDARG"); return E_INVALIDARG; } MfMediaStream* ptr_stream = new (std::nothrow) MfMediaStream(); if (!ptr_stream) { DBGLOG("null MfMediaStream, returning E_OUTOFMEMORY"); return E_OUTOFMEMORY; } HRESULT hr = ptr_stream->Create_(ptr_mfstream); if (FAILED(hr)) { DBGLOG("null MfMediaStream::Create_ failed" << HRLOG(hr)); return hr; } ptr_stream->AddRef(); *ptr_instance = ptr_stream; return hr; }
// IMFAsyncCallback method STDMETHODIMP MfMediaStream::Invoke(IMFAsyncResult* pAsyncResult) { stream_event_error_ = E_FAIL; MediaEventType event_type = MEError; IMFMediaEventPtr ptr_event; HRESULT hr = ptr_event_queue_->EndGetEvent(pAsyncResult, &ptr_event); if (FAILED(hr)) { DBGLOG("ERROR, EndGetEvent failed" << HRLOG(hr)); } else { hr = ptr_event->GetType(&event_type); if (FAILED(hr)) { DBGLOG("ERROR, cannot get event type" << HRLOG(hr)); } if (0 != expected_event_ && event_type != expected_event_) { DBGLOG("ERROR, unexpected event type, expected " << expected_event_ << " got " << event_type); stream_event_error_ = E_UNEXPECTED; } else { switch (event_type) { case MEMediaSample: DBGLOG("MEMediaSample"); stream_event_error_ = OnMediaSample_(ptr_event); if (FAILED(stream_event_error_)) { DBGLOG("MEMediaSample handling failed"); } break; case MEStreamPaused: DBGLOG("MEStreamPaused"); stream_event_error_ = OnStreamPaused_(ptr_event); if (FAILED(stream_event_error_)) { DBGLOG("MEStreamSeeked handling failed"); } break; case MEStreamSeeked: DBGLOG("MEStreamSeeked"); stream_event_error_ = OnStreamSeeked_(ptr_event); if (FAILED(stream_event_error_)) { DBGLOG("MEStreamSeeked handling failed"); } break; case MEStreamStarted: DBGLOG("MEStreamStarted"); stream_event_error_ = OnStreamStarted_(ptr_event); if (FAILED(stream_event_error_)) { DBGLOG("MEStreamStarted handling failed"); } break; case MEStreamStopped: DBGLOG("MEStreamStopped"); stream_event_error_ = OnStreamStopped_(ptr_event); if (FAILED(stream_event_error_)) { DBGLOG("MEStreamStopped handling failed"); } break; default: stream_event_error_ = E_UNEXPECTED; DBGLOG("unhandled event_type=" << event_type); break; } } } expected_event_ = 0; stream_event_recvd_ = event_type; return stream_event_.Set(); }