nsresult WMFReader::SeekInternal(int64_t aTargetUs) { DECODER_LOG("WMFReader::Seek() %lld", aTargetUs); MOZ_ASSERT(OnTaskQueue()); #ifdef DEBUG bool canSeek = false; GetSourceReaderCanSeek(mSourceReader, canSeek); NS_ASSERTION(canSeek, "WMFReader::Seek() should only be called if we can seek!"); #endif nsresult rv = ResetDecode(); NS_ENSURE_SUCCESS(rv, rv); // Mark that we must recapture the audio frame count from the next sample. // WMF doesn't set a discontinuity marker when we seek to time 0, so we // must remember to recapture the audio frame offset and reset the frame // sum on the next audio packet we decode. mMustRecaptureAudioPosition = true; AutoPropVar var; HRESULT hr = InitPropVariantFromInt64(UsecsToHNs(aTargetUs), &var); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); hr = mSourceReader->SetCurrentPosition(GUID_NULL, var); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); return NS_OK; }
nsresult WMFReader::Seek(int64_t aTargetUs, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime) { LOG("WMFReader::Seek() %lld", aTargetUs); NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread."); if (!mCanSeek) { return NS_ERROR_FAILURE; } nsresult rv = ResetDecode(); NS_ENSURE_SUCCESS(rv, rv); AutoPropVar var; HRESULT hr = InitPropVariantFromInt64(UsecsToHNs(aTargetUs), &var); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); hr = mSourceReader->SetCurrentPosition(GUID_NULL, var); NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE); return DecodeToTarget(aTargetUs); }
HRESULT MFTDecoder::CreateInputSample(const uint8_t* aData, uint32_t aDataSize, int64_t aTimestamp, RefPtr<IMFSample>* aOutSample) { NS_ENSURE_TRUE(mDecoder != nullptr, E_POINTER); HRESULT hr; RefPtr<IMFSample> sample; hr = wmf::MFCreateSample(byRef(sample)); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); RefPtr<IMFMediaBuffer> buffer; int32_t bufferSize = std::max<uint32_t>(uint32_t(mInputStreamInfo.cbSize), aDataSize); UINT32 alignment = (mInputStreamInfo.cbAlignment > 1) ? mInputStreamInfo.cbAlignment - 1 : 0; hr = wmf::MFCreateAlignedMemoryBuffer(bufferSize, alignment, byRef(buffer)); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); DWORD maxLength = 0; DWORD currentLength = 0; BYTE* dst = nullptr; hr = buffer->Lock(&dst, &maxLength, ¤tLength); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); // Copy data into sample's buffer. memcpy(dst, aData, aDataSize); hr = buffer->Unlock(); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); hr = buffer->SetCurrentLength(aDataSize); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); hr = sample->AddBuffer(buffer); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); hr = sample->SetSampleTime(UsecsToHNs(aTimestamp)); NS_ENSURE_TRUE(SUCCEEDED(hr), hr); *aOutSample = sample.forget(); return S_OK; }
HRESULT WMFAACDecoder::CreateInputSample(const uint8_t* aData, uint32_t aDataSize, Microseconds aTimestamp, IMFSample** aOutSample) { HRESULT hr; CComPtr<IMFSample> sample = nullptr; hr = MFCreateSample(&sample); ENSURE(SUCCEEDED(hr), hr); CComPtr<IMFMediaBuffer> buffer = nullptr; int32_t bufferSize = std::max<uint32_t>(uint32_t(mInputStreamInfo.cbSize), aDataSize); UINT32 alignment = (mInputStreamInfo.cbAlignment > 1) ? mInputStreamInfo.cbAlignment - 1 : 0; hr = MFCreateAlignedMemoryBuffer(bufferSize, alignment, &buffer); ENSURE(SUCCEEDED(hr), hr); DWORD maxLength = 0; DWORD currentLength = 0; BYTE* dst = nullptr; hr = buffer->Lock(&dst, &maxLength, ¤tLength); ENSURE(SUCCEEDED(hr), hr); // Copy data into sample's buffer. memcpy(dst, aData, aDataSize); hr = buffer->Unlock(); ENSURE(SUCCEEDED(hr), hr); hr = buffer->SetCurrentLength(aDataSize); ENSURE(SUCCEEDED(hr), hr); hr = sample->AddBuffer(buffer); ENSURE(SUCCEEDED(hr), hr); hr = sample->SetSampleTime(UsecsToHNs(aTimestamp)); ENSURE(SUCCEEDED(hr), hr); *aOutSample = sample.Detach(); return S_OK; }