예제 #1
0
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;
}
예제 #2
0
 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;
 }