bool DirectShowReader::DecodeAudioData() { MOZ_ASSERT(mDecoder->OnDecodeThread(), "Should be on decode thread."); HRESULT hr; SampleSink* sink = mAudioSinkFilter->GetSampleSink(); if (sink->AtEOS()) { // End of stream. return Finish(S_OK); } // Get the next chunk of audio samples. This blocks until the sample // arrives, or an error occurs (like the stream is shutdown). RefPtr<IMediaSample> sample; hr = sink->Extract(sample); if (FAILED(hr) || hr == S_FALSE) { return Finish(hr); } int64_t start = 0, end = 0; sample->GetMediaTime(&start, &end); LOG("DirectShowReader::DecodeAudioData [%4.2lf-%4.2lf]", RefTimeToSeconds(start), RefTimeToSeconds(end)); LONG length = sample->GetActualDataLength(); LONG numSamples = length / mBytesPerSample; LONG numFrames = length / mBytesPerSample / mNumChannels; BYTE* data = nullptr; hr = sample->GetPointer(&data); NS_ENSURE_TRUE(SUCCEEDED(hr), Finish(hr)); nsAutoArrayPtr<AudioDataValue> buffer(new AudioDataValue[numSamples]); AudioDataValue* dst = buffer.get(); if (mBytesPerSample == 1) { uint8_t* src = reinterpret_cast<uint8_t*>(data); for (int32_t i = 0; i < numSamples; ++i) { dst[i] = UnsignedByteToAudioSample(src[i]); } } else if (mBytesPerSample == 2) { int16_t* src = reinterpret_cast<int16_t*>(data); for (int32_t i = 0; i < numSamples; ++i) { dst[i] = AudioSampleToFloat(src[i]); } } mAudioQueue.Push(new AudioData(mDecoder->GetResource()->Tell(), RefTimeToUsecs(start), RefTimeToUsecs(end - start), numFrames, buffer.forget(), mNumChannels)); return true; }
uint32_t operator()(AudioDataValue *aBuffer, uint32_t aSamples) { uint32_t maxSamples = std::min(aSamples, mSamples - mNextSample); uint32_t frames = maxSamples / mChannels; size_t byteOffset = mNextSample * mBytesPerSample; if (mBytesPerSample == 1) { for (uint32_t i = 0; i < maxSamples; ++i) { uint8_t *sample = mSource + byteOffset; aBuffer[i] = UnsignedByteToAudioSample(*sample); byteOffset += mBytesPerSample; } } else if (mBytesPerSample == 2) { for (uint32_t i = 0; i < maxSamples; ++i) { int16_t *sample = reinterpret_cast<int16_t *>(mSource + byteOffset); aBuffer[i] = AudioSampleToFloat(*sample); byteOffset += mBytesPerSample; } } mNextSample += maxSamples; return frames; }