HRESULT TvideoCodecQuickSync::decompress(const unsigned char *src, size_t srcLen, IMediaSample *pIn) { if (!ok) { return E_UNEXPECTED; } CAutoLock lock(&m_csLock); IMediaSample* pMediaSample = pIn; TfakeMediaSample* pFakeMediaSample = (E_NOTIMPL == pIn->GetActualDataLength()) ? static_cast<TfakeMediaSample*>(pIn) : NULL; // VFW flow if (NULL != pFakeMediaSample) { m_MediaSample.SetDiscontinuity(pFakeMediaSample->IsDiscontinuity() == S_OK ? TRUE : FALSE); m_MediaSample.SetSyncPoint(pFakeMediaSample->IsSyncPoint() == S_OK ? TRUE : FALSE); m_MediaSample.SetPointer(const_cast<BYTE*>(src), (LONG)srcLen); m_MediaSample.SetActualDataLength((LONG)srcLen); pMediaSample = &m_MediaSample; } bool isSyncPoint = pMediaSample->IsSyncPoint() == S_OK; HRESULT hr = m_QuickSync->Decode(pMediaSample); if (pMediaSample->IsPreroll() == S_OK) { return sinkD->deliverPreroll((isSyncPoint) ? FRAME_TYPE::I : FRAME_TYPE::P); } return hr; }
HRESULT MediaChunk::Write(Atom* patm) { // record chunk start position LONGLONG posChunk = patm->Position() + patm->Length(); if (m_bOldIndexFormat) { long cBytes = 0; // ensure that we don't break in the middle of a sample (Maxim Kartavenkov) const int MAX_PCM_SIZE = 22050; int max_bytes = MAX_PCM_SIZE - (MAX_PCM_SIZE % m_pTrack->Handler()->BlockAlign()); list<IMediaSample*>::iterator it = m_Samples.begin(); long cAvail = 0; BYTE* pBuffer = NULL; for (;;) { if (!cAvail) { if (it == m_Samples.end()) { break; } IMediaSample* pSample = *it++; pSample->GetPointer(&pBuffer); cAvail = pSample->GetActualDataLength(); REFERENCE_TIME tStart, tStop; if (SUCCEEDED(pSample->GetTime(&tStart, &tStop))) { m_pTrack->SetOldIndexStart(tStart); } } long cThis = max_bytes - cBytes; if (cThis > cAvail) { cThis = cAvail; } int cActual = 0; m_pTrack->Handler()->WriteData(patm, pBuffer, cThis, &cActual); cBytes += cActual; cAvail -= cActual; pBuffer += cActual; if (cBytes >= max_bytes) { m_pTrack->OldIndex(posChunk, cBytes); posChunk = patm->Position() + patm->Length(); cBytes = 0; } } if (cBytes) { m_pTrack->OldIndex(posChunk, cBytes); } return S_OK; } // Remember that large H264 samples may be broken // across several buffers, with Sync flag at start and // time on last buffer. bool bSync = false; long cBytes = 0; long nSamples = 0; // loop once through the samples writing the data list<IMediaSample*>::iterator it; for (it = m_Samples.begin(); it != m_Samples.end(); it++) { IMediaSample* pSample = *it; // record positive sync flag, but for // multiple-buffer samples, only one sync flag will be present // so don't overwrite with later negatives. if (pSample->IsSyncPoint() == S_OK) { bSync = true; } // write payload, including any transformation (eg BSF to length-prepended) BYTE* pBuffer; pSample->GetPointer(&pBuffer); int cActual = 0; m_pTrack->Handler()->WriteData(patm, pBuffer, pSample->GetActualDataLength(), &cActual); cBytes += cActual; REFERENCE_TIME tStart, tEnd; HRESULT hr = pSample->GetTime(&tStart, &tEnd); if (SUCCEEDED(hr)) { // this is the last buffer in the sample m_pTrack->IndexSample(bSync, tStart, tEnd, cBytes); // reset for new sample bSync = false; cBytes = 0; nSamples++; } } // add chunk position to index m_pTrack->IndexChunk(posChunk, nSamples); return S_OK; }