HRESULT CLAVOutputPin::DeliverPacket(Packet *pPacket) { HRESULT hr = S_OK; IMediaSample *pSample = NULL; long nBytes = (long)pPacket->GetDataSize(); if(nBytes == 0) { goto done; } CHECK_HR(hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0)); if (m_bPacketAllocator) { ILAVMediaSample *pLAVSample = NULL; CHECK_HR(hr = pSample->QueryInterface(&pLAVSample)); CHECK_HR(hr = pLAVSample->SetPacket(pPacket)); SafeRelease(&pLAVSample); } else { // Resize buffer if it is too small // This can cause a playback hick-up, we should avoid this if possible by setting a big enough buffer size if(nBytes > pSample->GetSize()) { SafeRelease(&pSample); ALLOCATOR_PROPERTIES props, actual; CHECK_HR(hr = m_pAllocator->GetProperties(&props)); // Give us 2 times the requested size, so we don't resize every time props.cbBuffer = nBytes*2; if(props.cBuffers > 1) { CHECK_HR(hr = __super::DeliverBeginFlush()); CHECK_HR(hr = __super::DeliverEndFlush()); } CHECK_HR(hr = m_pAllocator->Decommit()); CHECK_HR(hr = m_pAllocator->SetProperties(&props, &actual)); CHECK_HR(hr = m_pAllocator->Commit()); CHECK_HR(hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0)); } // Fill the sample BYTE* pData = NULL; if(FAILED(hr = pSample->GetPointer(&pData)) || !pData) goto done; memcpy(pData, pPacket->GetData(), nBytes); } if(pPacket->pmt) { DbgLog((LOG_TRACE, 10, L"::DeliverPacket() - sending new media type to decoder")); pSample->SetMediaType(pPacket->pmt); pPacket->bDiscontinuity = true; CAutoLock cAutoLock(m_pLock); CMediaType pmt = *(pPacket->pmt); m_mts.clear(); m_mts.push_back(pmt); pPacket->pmt = NULL; SetMediaType(&pmt); } bool fTimeValid = pPacket->rtStart != Packet::INVALID_TIME; CHECK_HR(hr = pSample->SetActualDataLength(nBytes)); CHECK_HR(hr = pSample->SetTime(fTimeValid ? &pPacket->rtStart : NULL, fTimeValid ? &pPacket->rtStop : NULL)); CHECK_HR(hr = pSample->SetMediaTime(NULL, NULL)); CHECK_HR(hr = pSample->SetDiscontinuity(pPacket->bDiscontinuity)); CHECK_HR(hr = pSample->SetSyncPoint(pPacket->bSyncPoint)); CHECK_HR(hr = pSample->SetPreroll(fTimeValid && pPacket->rtStart < 0)); // Deliver CHECK_HR(hr = Deliver(pSample)); done: if (!m_bPacketAllocator) SAFE_DELETE(pPacket); SafeRelease(&pSample); return hr; }
HRESULT CLAVOutputPin::DeliverPacket(Packet *pPacket) { HRESULT hr = S_OK; IMediaSample *pSample = nullptr; long nBytes = (long)pPacket->GetDataSize(); if(nBytes == 0) { goto done; } CHECK_HR(hr = GetDeliveryBuffer(&pSample, nullptr, nullptr, 0)); if (m_bPacketAllocator) { ILAVMediaSample *pLAVSample = nullptr; CHECK_HR(hr = pSample->QueryInterface(&pLAVSample)); CHECK_HR(hr = pLAVSample->SetPacket(pPacket)); SafeRelease(&pLAVSample); } else { // Resize buffer if it is too small // This can cause a playback hick-up, we should avoid this if possible by setting a big enough buffer size if(nBytes > pSample->GetSize()) { SafeRelease(&pSample); ALLOCATOR_PROPERTIES props, actual; CHECK_HR(hr = m_pAllocator->GetProperties(&props)); // Give us 2 times the requested size, so we don't resize every time props.cbBuffer = nBytes*2; if(props.cBuffers > 1) { CHECK_HR(hr = __super::DeliverBeginFlush()); CHECK_HR(hr = __super::DeliverEndFlush()); } CHECK_HR(hr = m_pAllocator->Decommit()); CHECK_HR(hr = m_pAllocator->SetProperties(&props, &actual)); CHECK_HR(hr = m_pAllocator->Commit()); CHECK_HR(hr = GetDeliveryBuffer(&pSample, nullptr, nullptr, 0)); } // Fill the sample BYTE* pData = nullptr; if(FAILED(hr = pSample->GetPointer(&pData)) || !pData) goto done; memcpy(pData, pPacket->GetData(), nBytes); } if(pPacket->pmt) { DbgLog((LOG_TRACE, 10, L"::DeliverPacket() - sending new media type to decoder")); pSample->SetMediaType(pPacket->pmt); pPacket->bDiscontinuity = true; CAutoLock cAutoLock(m_pLock); CMediaType pmt = *(pPacket->pmt); m_mts.clear(); m_mts.push_back(pmt); pPacket->pmt = nullptr; SetMediaType(&pmt); } bool fTimeValid = pPacket->rtStart != Packet::INVALID_TIME; // IBitRateInfo m_BitRate.nBytesSinceLastDeliverTime += nBytes; if (fTimeValid) { if (m_BitRate.rtLastDeliverTime == Packet::INVALID_TIME) { m_BitRate.rtLastDeliverTime = pPacket->rtStart; m_BitRate.nBytesSinceLastDeliverTime = 0; } if (m_BitRate.rtLastDeliverTime + 10000000 < pPacket->rtStart) { REFERENCE_TIME rtDiff = pPacket->rtStart - m_BitRate.rtLastDeliverTime; double dSecs, dBits; dSecs = rtDiff / 10000000.0; dBits = 8.0 * m_BitRate.nBytesSinceLastDeliverTime; m_BitRate.nCurrentBitRate = (DWORD)(dBits / dSecs); m_BitRate.rtTotalTimeDelivered += rtDiff; m_BitRate.nTotalBytesDelivered += m_BitRate.nBytesSinceLastDeliverTime; dSecs = m_BitRate.rtTotalTimeDelivered / 10000000.0; dBits = 8.0 * m_BitRate.nTotalBytesDelivered; m_BitRate.nAverageBitRate = (DWORD)(dBits / dSecs); m_BitRate.rtLastDeliverTime = pPacket->rtStart; m_BitRate.nBytesSinceLastDeliverTime = 0; } } CHECK_HR(hr = pSample->SetActualDataLength(nBytes)); CHECK_HR(hr = pSample->SetTime(fTimeValid ? &pPacket->rtStart : nullptr, fTimeValid ? &pPacket->rtStop : nullptr)); CHECK_HR(hr = pSample->SetMediaTime(nullptr, nullptr)); CHECK_HR(hr = pSample->SetDiscontinuity(pPacket->bDiscontinuity)); CHECK_HR(hr = pSample->SetSyncPoint(pPacket->bSyncPoint)); CHECK_HR(hr = pSample->SetPreroll(fTimeValid && pPacket->rtStart < 0)); // Deliver CHECK_HR(hr = Deliver(pSample)); done: if (!m_bPacketAllocator || !pSample) SAFE_DELETE(pPacket); SafeRelease(&pSample); return hr; }