示例#1
0
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;
}
示例#2
0
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;
}