Beispiel #1
0
// aTime is the time in ms the samples were inserted into MediaStreamGraph
nsresult
AudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames)
{
    MonitorAutoLock mon(mMonitor);

    if (mState == ERRORED) {
        return NS_ERROR_FAILURE;
    }
    NS_ASSERTION(mState == INITIALIZED || mState == STARTED || mState == RUNNING,
                 "Stream write in unexpected state.");

    // Downmix to Stereo.
    if (mChannels > 2 && mChannels <= 8) {
        DownmixAudioToStereo(const_cast<AudioDataValue*> (aBuf), mChannels, aFrames);
    } else if (mChannels > 8) {
        return NS_ERROR_FAILURE;
    }

    if (mChannels >= 2 && mIsMonoAudioEnabled) {
        DownmixStereoToMono(const_cast<AudioDataValue*> (aBuf), aFrames);
    }

    const uint8_t* src = reinterpret_cast<const uint8_t*>(aBuf);
    uint32_t bytesToCopy = FramesToBytes(aFrames);

    while (bytesToCopy > 0) {
        uint32_t available = std::min(bytesToCopy, mBuffer.Available());
        MOZ_ASSERT(available % mBytesPerFrame == 0,
                   "Must copy complete frames.");

        mBuffer.AppendElements(src, available);
        src += available;
        bytesToCopy -= available;

        if (bytesToCopy > 0) {
            // If we are not playing, but our buffer is full, start playing to make
            // room for soon-to-be-decoded data.
            if (mState != STARTED && mState != RUNNING) {
                MOZ_LOG(gAudioStreamLog, LogLevel::Warning, ("Starting stream %p in Write (%u waiting)",
                        this, bytesToCopy));
                StartUnlocked();
                if (mState == ERRORED) {
                    return NS_ERROR_FAILURE;
                }
            }
            MOZ_LOG(gAudioStreamLog, LogLevel::Warning, ("Stream %p waiting in Write() (%u waiting)",
                    this, bytesToCopy));
            mon.Wait();
        }
    }

    mWritten += aFrames;
    return NS_OK;
}
Beispiel #2
0
bool
AudioStream::Downmix(Chunk* aChunk)
{
    if (aChunk->Rate() != mInRate) {
        LOGW("mismatched sample %u, mInRate=%u", aChunk->Rate(), mInRate);
        return false;
    }

    if (aChunk->Channels() > 8) {
        return false;
    }

    if (aChunk->Channels() > 2 && aChunk->Channels() <= 8) {
        DownmixAudioToStereo(aChunk->GetWritable(),
                             aChunk->Channels(),
                             aChunk->Frames());
    }

    if (aChunk->Channels() >= 2 && mIsMonoAudioEnabled) {
        DownmixStereoToMono(aChunk->GetWritable(), aChunk->Frames());
    }

    return true;
}