HRESULT FlvStream::DispatchSamples() { HRESULT hr = S_OK; SourceLock lock(source); // An I/O request can complete after the source is paused, stopped, or // shut down. Do not deliver samples unless the source is running. if (m_state != SourceState::STATE_STARTED) { return S_OK; } // Deliver as many samples as we can. while (ok(hr) && !samples.empty() && !requests.empty()) { IMFSamplePtr sample = samples.pop_front(); ComPtr<IUnknown> token = requests.pop_front(); // Pull the next request token from the queue. Tokens can be NULL. assert(sample); // token can be null if (token) hr = sample->SetUnknown(MFSampleExtension_Token, token.Get()); // Send an MEMediaSample event with the sample. if(ok(hr)) hr = event_queue->QueueEventParamUnk(MEMediaSample, GUID_NULL, S_OK, sample.Get()); } if (ok(hr) && samples.empty() && eos) { // The sample queue is empty AND we have reached the end of the source // stream. Notify the pipeline by sending the end-of-stream event. hr = event_queue->QueueEventParamVar( MEEndOfStream, GUID_NULL, S_OK, NULL); // Notify the source. It will send the end-of-presentation event. // hr = m_pSource->QueueAsyncOperation(SourceOp::OP_END_OF_STREAM); hr = source->AsyncEndOfStream(); } else if (ok(hr) && NeedsData() == S_OK) { // The sample queue is empty; the request queue is not empty; and we // have not reached the end of the stream. Ask for more data. hr = source->AsyncRequestData(); } if (FAILED(hr) && (m_state != SourceState::STATE_SHUTDOWN)) { // An error occurred. Send an MEError even from the source, // unless the source is already shut down. source->QueueEvent(MEError, GUID_NULL, hr, NULL); } return S_OK; }
HRESULT MPEG1Stream::DispatchSamples() { HRESULT hr = S_OK; BOOL bNeedData = FALSE; BOOL bEOS = FALSE; IMFSample *pSample = NULL; IUnknown *pToken = NULL; SourceLock lock(m_pSource); // It's possible that an I/O request completed after the source // paused, stopped, or shut down. We should not deliver any samples // unless the source is running. if (m_state != STATE_STARTED) { hr = S_OK; goto done; } // Deliver as many samples as we can. while (!m_Samples.IsEmpty() && !m_Requests.IsEmpty()) { // Pull the next sample from the queue. CHECK_HR(hr = m_Samples.RemoveFront(&pSample)); // Pull the next request token from the queue. Tokens can be NULL. CHECK_HR(hr = m_Requests.RemoveFront(&pToken)); if (pToken) { CHECK_HR(hr = pSample->SetUnknown(MFSampleExtension_Token, pToken)); } CHECK_HR(hr = m_pEventQueue->QueueEventParamUnk(MEMediaSample, GUID_NULL, S_OK, pSample)); SAFE_RELEASE(pSample); SAFE_RELEASE(pToken); } if (m_Samples.IsEmpty() && m_bEOS) { // The sample queue is empty AND we have reached the end of the source stream. // Notify the pipeline by sending the end-of-stream event. CHECK_HR(hr = m_pEventQueue->QueueEventParamVar(MEEndOfStream, GUID_NULL, S_OK, NULL)); // Also notify the source, so that it can send the end-of-presentation event. CHECK_HR(hr = m_pSource->QueueAsyncOperation(SourceOp::OP_END_OF_STREAM)); } else if (NeedsData()) { // The sample queue is empty and the request queue is not empty (and we did not // reach the end of the stream). Ask the source for more data. CHECK_HR(hr = m_pSource->QueueAsyncOperation(SourceOp::OP_REQUEST_DATA)); } done: // If there was an error, queue MEError from the source (except after shutdown). if (FAILED(hr) && (m_state != STATE_SHUTDOWN)) { m_pSource->QueueEvent(MEError, GUID_NULL, hr, NULL); } SAFE_RELEASE(pSample); SAFE_RELEASE(pToken); return S_OK; }
void CMPEG1Stream::DispatchSamples() throw() { // An I/O request can complete after the source is paused, stopped, or // shut down. Do not deliver samples unless the source is running. if (m_state != STATE_STARTED) { return; } try { // Deliver as many samples as we can. while (!m_Samples.IsEmpty() && !m_Requests.IsEmpty()) { ComPtr<IMFSample> spSample; ComPtr<IUnknown> spToken; // Pull the next sample from the queue. ThrowIfError(m_Samples.RemoveFront(&spSample)); // Pull the next request token from the queue. Tokens can be nullptr. ThrowIfError(m_Requests.RemoveFront(&spToken)); if (spToken != nullptr) { // Set the token on the sample. ThrowIfError(spSample->SetUnknown(MFSampleExtension_Token, spToken.Get())); } // Send an MEMediaSample event with the sample. ThrowIfError(m_spEventQueue->QueueEventParamUnk(MEMediaSample, GUID_NULL, S_OK, spSample.Get())); } if (m_Samples.IsEmpty() && m_fEOS) { // The sample queue is empty AND we have reached the end of the source // stream. Notify the pipeline by sending the end-of-stream event. ThrowIfError(m_spEventQueue->QueueEventParamVar( MEEndOfStream, GUID_NULL, S_OK, nullptr)); // Notify the source. It will send the end-of-presentation event. ThrowIfError(m_spSource->QueueAsyncOperation(SourceOp::OP_END_OF_STREAM)); } else if (NeedsData()) { // The sample queue is empty; the request queue is not empty; and we // have not reached the end of the stream. Ask for more data. ThrowIfError(m_spSource->QueueAsyncOperation(SourceOp::OP_REQUEST_DATA)); } } catch (Exception ^exc) { if (m_state != STATE_SHUTDOWN) { // An error occurred. Send an MEError even from the source, // unless the source is already shut down. m_spSource->QueueEvent(MEError, GUID_NULL, exc->HResult, nullptr); } } }
HRESULT PpboxStream::DispatchSamples() { HRESULT hr = S_OK; BOOL bNeedData = FALSE; BOOL bEOS = FALSE; SourceLock lock(m_pSource); // An I/O request can complete after the source is paused, stopped, or // shut down. Do not deliver samples unless the source is running. if (m_state != STATE_STARTED) { return S_OK; } IMFSample *pSample = NULL; IUnknown *pToken = NULL; // Deliver as many samples as we can. while (!m_Samples.IsEmpty() && !m_Requests.IsEmpty()) { // Pull the next sample from the queue. hr = m_Samples.RemoveFront(&pSample); if (FAILED(hr)) { goto done; } // Pull the next request token from the queue. Tokens can be NULL. hr = m_Requests.RemoveFront(&pToken); if (FAILED(hr)) { goto done; } if (pToken) { // Set the token on the sample. hr = pSample->SetUnknown(MFSampleExtension_Token, pToken); if (FAILED(hr)) { goto done; } } // Send an MEMediaSample event with the sample. hr = m_pEventQueue->QueueEventParamUnk( MEMediaSample, GUID_NULL, S_OK, pSample); if (FAILED(hr)) { goto done; } SafeRelease(&pSample); SafeRelease(&pToken); } if (m_Samples.IsEmpty() && m_bEOS) { // The sample queue is empty AND we have reached the end of the source // stream. Notify the pipeline by sending the end-of-stream event. hr = m_pEventQueue->QueueEventParamVar( MEEndOfStream, GUID_NULL, S_OK, NULL); if (FAILED(hr)) { goto done; } // Notify the source. It will send the end-of-presentation event. hr = m_pSource->RequestSample(); if (FAILED(hr)) { goto done; } } else if (NeedsData()) { // The sample queue is empty; the request queue is not empty; and we // have not reached the end of the stream. Ask for more data. hr = m_pSource->RequestSample(); if (FAILED(hr)) { goto done; } } else { hr = S_OK; goto done; } done: if (FAILED(hr) && (m_state != STATE_SHUTDOWN)) { // An error occurred. Send an MEError even from the source, // unless the source is already shut down. m_pSource->QueueEvent(MEError, GUID_NULL, hr, NULL); } SafeRelease(&pSample); SafeRelease(&pToken); return S_OK; }