HRESULT WavStream::CreateAudioSample(IMFSample **ppSample) { HRESULT hr = S_OK; IMFMediaBuffer *pBuffer = NULL; IMFSample *pSample = NULL; DWORD cbBuffer = 0; BYTE *pData = NULL; LONGLONG duration = 0; // Start with one second of data, rounded up to the nearest block. cbBuffer = AlignUp<DWORD>(m_pRiff->Format()->nAvgBytesPerSec, m_pRiff->Format()->nBlockAlign); // Don't request any more than what's left. cbBuffer = min(cbBuffer, m_pRiff->BytesRemainingInChunk()); // Create the buffer. hr = MFCreateMemoryBuffer(cbBuffer, &pBuffer); // Get a pointer to the buffer memory. if (SUCCEEDED(hr)) { hr = pBuffer->Lock(&pData, NULL, NULL); } // Fill the buffer if (SUCCEEDED(hr)) { hr = m_pRiff->ReadDataFromChunk(pData, cbBuffer); } // Unlock the buffer. if (SUCCEEDED(hr)) { hr = pBuffer->Unlock(); pData = NULL; } // Set the size of the valid data in the buffer. if (SUCCEEDED(hr)) { hr = pBuffer->SetCurrentLength(cbBuffer); } // Create a new sample and add the buffer to it. if (SUCCEEDED(hr)) { hr = MFCreateSample(&pSample); } if (SUCCEEDED(hr)) { hr = pSample->AddBuffer(pBuffer); } // Set the time stamps, duration, and sample flags. if (SUCCEEDED(hr)) { hr = pSample->SetSampleTime(m_rtCurrentPosition); } if (SUCCEEDED(hr)) { duration = AudioDurationFromBufferSize(m_pRiff->Format(), cbBuffer); hr = pSample->SetSampleDuration(duration); } // Set the discontinuity flag. if (SUCCEEDED(hr)) { if (m_discontinuity) { hr = pSample->SetUINT32(MFSampleExtension_Discontinuity, TRUE); } } if (SUCCEEDED(hr)) { // Update our current position. m_rtCurrentPosition += duration; // Give the pointer to the caller. *ppSample = pSample; (*ppSample)->AddRef(); } if (pData && pBuffer) { hr = pBuffer->Unlock(); } SafeRelease(&pBuffer); SafeRelease(&pSample); return hr; }
STDMETHODIMP CDecWMV9MFT::Decode(const BYTE *buffer, int buflen, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, BOOL bSyncPoint, BOOL bDiscontinuity, IMediaSample *pMediaSample) { HRESULT hr = S_OK; DWORD dwStatus = 0; hr = m_pMFT->GetInputStatus(0, &dwStatus); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> GetInputStatus() failed with hr: 0x%x", hr)); return S_FALSE; } if (!(dwStatus & MFT_INPUT_STATUS_ACCEPT_DATA)) return S_FALSE; if (m_vc1Header && (m_bManualReorder || m_bNeedKeyFrame)) { AVPictureType pictype = m_vc1Header->ParseVC1PictureType(buffer, buflen); if (m_bManualReorder) { if (pictype == AV_PICTURE_TYPE_I || pictype == AV_PICTURE_TYPE_P) { if (m_bReorderBufferValid) m_timestampQueue.push(m_rtReorderBuffer); m_rtReorderBuffer = rtStart; m_bReorderBufferValid = TRUE; } else { m_timestampQueue.push(rtStart); } } if (m_bNeedKeyFrame) { if (pictype != AV_PICTURE_TYPE_I) { if (m_bManualReorder) m_timestampQueue.pop(); return S_OK; } else { m_bNeedKeyFrame = FALSE; bSyncPoint = TRUE; } } } IMFSample *pSample = nullptr; hr = MF.CreateSample(&pSample); if (FAILED(hr)) { DbgLog((LOG_ERROR, 10, L"Unable to allocate MF Sample, hr: 0x%x", hr)); return E_FAIL; } IMFMediaBuffer *pMFBuffer = CreateMediaBuffer(buffer, buflen); if (!pMFBuffer) { DbgLog((LOG_TRACE, 10, L"Unable to allocate media buffer")); SafeRelease(&pSample); return E_FAIL; } pSample->AddBuffer(pMFBuffer); if (rtStart != AV_NOPTS_VALUE) { pSample->SetSampleTime(rtStart); if (rtStop != AV_NOPTS_VALUE && rtStop > (rtStart - 1)) pSample->SetSampleDuration(rtStop - rtStart); } pSample->SetUINT32(MFSampleExtension_CleanPoint, bSyncPoint); pSample->SetUINT32(MFSampleExtension_Discontinuity, bDiscontinuity); hr = m_pMFT->ProcessInput(0, pSample, 0); if (hr == MF_E_NOTACCEPTING) { // Not accepting data right now, try to process output and try again ProcessOutput(); hr = m_pMFT->ProcessInput(0, pSample, 0); } SafeRelease(&pMFBuffer); SafeRelease(&pSample); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> ProcessInput failed with hr: 0x%x", hr)); return E_FAIL; } return ProcessOutput(); }