Bug 1524890 - P11. Remove duration from AudioData construction parameter. r=bryce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 22 Feb 2019 09:19:47 +0000
changeset 460799 9b93c2718c181e8f2b7dfc0df6a0032163626300
parent 460798 08fd6ddd88e4750923b58fd8af0643a8c8d7507a
child 460800 c3f6ea574cdfcf501513ed10c2f2320f7a47a09c
push id35603
push userdluca@mozilla.com
push dateMon, 25 Feb 2019 01:46:40 +0000
treeherdermozilla-central@3a2ced4fbd98 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbryce
bugs1524890
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1524890 - P11. Remove duration from AudioData construction parameter. r=bryce It can be determined from the size of the buffer and the number of audio frames. Additionally, it ensures that the duration of the frame is always exactly what the AudioData contains. Differential Revision: https://phabricator.services.mozilla.com/D20170
dom/media/AudioCompactor.h
dom/media/MediaData.cpp
dom/media/MediaData.h
dom/media/ipc/RemoteAudioDecoder.cpp
dom/media/mediasink/AudioSink.cpp
dom/media/platforms/agnostic/BlankDecoderModule.cpp
dom/media/platforms/agnostic/OpusDecoder.cpp
dom/media/platforms/agnostic/VorbisDecoder.cpp
dom/media/platforms/agnostic/WAVDecoder.cpp
dom/media/platforms/android/RemoteDataDecoder.cpp
dom/media/platforms/apple/AppleATDecoder.cpp
dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
dom/media/platforms/wmf/WMFAudioMFTManager.cpp
--- a/dom/media/AudioCompactor.h
+++ b/dom/media/AudioCompactor.h
@@ -61,18 +61,20 @@ class AudioCompactor {
       NS_ASSERTION(framesCopied <= aFrames, "functor copied too many frames");
       buffer.SetLength(size_t(framesCopied) * aChannels);
 
       auto duration = FramesToTimeUnit(framesCopied, aSampleRate);
       if (!duration.IsValid()) {
         return false;
       }
 
-      mQueue.Push(new AudioData(aOffset, time, duration, std::move(buffer),
-                                aChannels, aSampleRate));
+      RefPtr<AudioData> data = new AudioData(aOffset, time, std::move(buffer),
+                                             aChannels, aSampleRate);
+      MOZ_DIAGNOSTIC_ASSERT(duration == data->mDuration, "must be equal");
+      mQueue.Push(data);
 
       // Remove the frames we just pushed into the queue and loop if there is
       // more to be done.
       time += duration;
       aFrames -= framesCopied;
 
       // NOTE: No need to update aOffset as its only an approximation anyway.
     }
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -35,16 +35,28 @@ const char* VideoData::sTypeName = "vide
 bool IsDataLoudnessHearable(const AudioDataValue aData) {
   // We can transfer the digital value to dBFS via following formula. According
   // to American SMPTE standard, 0 dBu equals -20 dBFS. In theory 0 dBu is still
   // hearable, so we choose a smaller value as our threshold. If the loudness
   // is under this threshold, it might not be hearable.
   return 20.0f * std::log10(AudioSampleToFloat(aData)) > -100;
 }
 
+AudioData::AudioData(int64_t aOffset, const media::TimeUnit& aTime,
+                     AlignedAudioBuffer&& aData, uint32_t aChannels,
+                     uint32_t aRate, uint32_t aChannelMap)
+    : MediaData(sType, aOffset, aTime,
+                FramesToTimeUnit(aData.Length() / aChannels, aRate)),
+      mChannels(aChannels),
+      mChannelMap(aChannelMap),
+      mRate(aRate),
+      mOriginalTime(aTime),
+      mAudioData(std::move(aData)),
+      mFrames(mAudioData.Length() / aChannels) {}
+
 Span<AudioDataValue> AudioData::Data() const {
   return MakeSpan(GetAdjustedData(), mFrames * mChannels);
 }
 
 bool AudioData::AdjustForStartTime(int64_t aStartTime) {
   const TimeUnit startTimeOffset =
       media::TimeUnit::FromMicroseconds(aStartTime);
   mOriginalTime -= startTimeOffset;
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -329,26 +329,18 @@ class NullData : public MediaData {
 
   static const Type sType = Type::NULL_DATA;
 };
 
 // Holds chunk a decoded audio frames.
 class AudioData : public MediaData {
  public:
   AudioData(int64_t aOffset, const media::TimeUnit& aTime,
-            const media::TimeUnit& aDuration, AlignedAudioBuffer&& aData,
-            uint32_t aChannels, uint32_t aRate,
-            uint32_t aChannelMap = AudioConfig::ChannelLayout::UNKNOWN_MAP)
-      : MediaData(sType, aOffset, aTime, aDuration),
-        mChannels(aChannels),
-        mChannelMap(aChannelMap),
-        mRate(aRate),
-        mOriginalTime(aTime),
-        mAudioData(std::move(aData)),
-        mFrames(mAudioData.Length() / aChannels) {}
+            AlignedAudioBuffer&& aData, uint32_t aChannels, uint32_t aRate,
+            uint32_t aChannelMap = AudioConfig::ChannelLayout::UNKNOWN_MAP);
 
   static const Type sType = Type::AUDIO_DATA;
   static const char* sTypeName;
 
   // Access the buffer as a Span.
   Span<AudioDataValue> Data() const;
 
   // Amount of frames for contained data.
--- a/dom/media/ipc/RemoteAudioDecoder.cpp
+++ b/dom/media/ipc/RemoteAudioDecoder.cpp
@@ -24,17 +24,16 @@ mozilla::ipc::IPCResult RemoteAudioDecod
   PodCopy(alignedAudioBuffer.Data(), aData.buffer().get<AudioDataValue>(),
           alignedAudioBuffer.Length());
 
   DeallocShmem(aData.buffer());
 
   RefPtr<AudioData> audio =
       new AudioData(aData.base().offset(),
                     media::TimeUnit::FromMicroseconds(aData.base().time()),
-                    media::TimeUnit::FromMicroseconds(aData.base().duration()),
                     std::move(alignedAudioBuffer), aData.channels(),
                     aData.rate(), aData.channelMap());
 
   mDecodedData.AppendElement(std::move(audio));
   return IPC_OK();
 }
 
 MediaResult RemoteAudioDecoderChild::InitIPDL(
--- a/dom/media/mediasink/AudioSink.cpp
+++ b/dom/media/mediasink/AudioSink.cpp
@@ -450,18 +450,19 @@ already_AddRefed<AudioData> AudioSink::C
   }
   auto duration = FramesToTimeUnit(frames, mOutputRate);
   if (!duration.IsValid()) {
     NS_WARNING("Int overflow in AudioSink");
     mErrored = true;
     return nullptr;
   }
   RefPtr<AudioData> data =
-      new AudioData(aReference->mOffset, aReference->mTime, duration,
-                    std::move(aBuffer), mOutputChannels, mOutputRate);
+      new AudioData(aReference->mOffset, aReference->mTime, std::move(aBuffer),
+                    mOutputChannels, mOutputRate);
+  MOZ_DIAGNOSTIC_ASSERT(duration == data->mDuration, "must be equal");
   return data.forget();
 }
 
 uint32_t AudioSink::DrainConverter(uint32_t aMaxFrames) {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
 
   if (!mConverter || !mLastProcessedPacket || !aMaxFrames) {
     // nothing to drain.
--- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp
@@ -99,18 +99,19 @@ already_AddRefed<MediaData> BlankAudioDa
   for (int i = 0; i < frames.value(); i++) {
     float f = sin(2 * pi * noteHz * mFrameSum / mSampleRate);
     for (unsigned c = 0; c < mChannelCount; c++) {
       samples[i * mChannelCount + c] = AudioDataValue(f);
     }
     mFrameSum++;
   }
   RefPtr<AudioData> data(new AudioData(aSample->mOffset, aSample->mTime,
-                                       aSample->mDuration, std::move(samples),
-                                       mChannelCount, mSampleRate));
+                                       std::move(samples), mChannelCount,
+                                       mSampleRate));
+  MOZ_DIAGNOSTIC_ASSERT(aSample->mDuration == data->mDuration, "must be equal");
   return data.forget();
 }
 
 already_AddRefed<MediaDataDecoder> BlankDecoderModule::CreateVideoDecoder(
     const CreateDecoderParams& aParams) {
   const VideoInfo& config = aParams.VideoConfig();
   UniquePtr<DummyDataCreator> creator = MakeUnique<BlankVideoDataCreator>(
       config.mDisplay.width, config.mDisplay.height, aParams.mImageContainer);
--- a/dom/media/platforms/agnostic/OpusDecoder.cpp
+++ b/dom/media/platforms/agnostic/OpusDecoder.cpp
@@ -328,19 +328,19 @@ RefPtr<MediaDataDecoder::DecodePromise> 
   if (!frames) {
     return DecodePromise::CreateAndResolve(DecodedData(), __func__);
   }
 
   // Trim extra allocated frames.
   buffer.SetLength(frames * channels);
 
   return DecodePromise::CreateAndResolve(
-      DecodedData{new AudioData(aSample->mOffset, time, duration,
-                                std::move(buffer), mOpusParser->mChannels,
-                                mOpusParser->mRate, mChannelMap)},
+      DecodedData{new AudioData(aSample->mOffset, time, std::move(buffer),
+                                mOpusParser->mChannels, mOpusParser->mRate,
+                                mChannelMap)},
       __func__);
 }
 
 RefPtr<MediaDataDecoder::DecodePromise> OpusDataDecoder::Drain() {
   RefPtr<OpusDataDecoder> self = this;
   // InvokeAsync dispatches a task that will be run after any pending decode
   // completes. As such, once the drain task run, there's nothing more to do.
   return InvokeAsync(mTaskQueue, __func__, [] {
--- a/dom/media/platforms/agnostic/VorbisDecoder.cpp
+++ b/dom/media/platforms/agnostic/VorbisDecoder.cpp
@@ -228,19 +228,21 @@ RefPtr<MediaDataDecoder::DecodePromise> 
       AudioConfig out(AudioConfig::ChannelLayout::SMPTEDefault(layout),
                       channels, rate);
       mAudioConverter = MakeUnique<AudioConverter>(in, out);
     }
     MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
     AudioSampleBuffer data(std::move(buffer));
     data = mAudioConverter->Process(std::move(data));
 
-    results.AppendElement(
-        new AudioData(aOffset, time, duration, data.Forget(), channels, rate,
-                      mAudioConverter->OutputConfig().Layout().Map()));
+    RefPtr<AudioData> audio =
+        new AudioData(aOffset, time, data.Forget(), channels, rate,
+                      mAudioConverter->OutputConfig().Layout().Map());
+    MOZ_DIAGNOSTIC_ASSERT(duration == audio->mDuration, "must be equal");
+    results.AppendElement(std::move(audio));
     mFrames += frames;
     err = vorbis_synthesis_read(&mVorbisDsp, frames);
     if (err) {
       return DecodePromise::CreateAndReject(
           MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
                       RESULT_DETAIL("vorbis_synthesis_read:%d", err)),
           __func__);
     }
--- a/dom/media/platforms/agnostic/WAVDecoder.cpp
+++ b/dom/media/platforms/agnostic/WAVDecoder.cpp
@@ -119,22 +119,19 @@ RefPtr<MediaDataDecoder::DecodePromise> 
           }
           buffer[i * mInfo.mChannels + j] =
               Int24bitToAudioSample<AudioDataValue>(res.unwrap());
         }
       }
     }
   }
 
-  auto duration = FramesToTimeUnit(frames, mInfo.mRate);
-
   return DecodePromise::CreateAndResolve(
-      DecodedData{new AudioData(aOffset, aSample->mTime, duration,
-                                std::move(buffer), mInfo.mChannels,
-                                mInfo.mRate)},
+      DecodedData{new AudioData(aOffset, aSample->mTime, std::move(buffer),
+                                mInfo.mChannels, mInfo.mRate)},
       __func__);
 }
 
 RefPtr<MediaDataDecoder::DecodePromise> WaveDataDecoder::Drain() {
   return InvokeAsync(mTaskQueue, __func__, [] {
     return DecodePromise::CreateAndResolve(DecodedData(), __func__);
   });
 }
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -427,29 +427,27 @@ class RemoteAudioDecoder : public Remote
 
     if (size > 0) {
 #ifdef MOZ_SAMPLE_TYPE_S16
       const int32_t numSamples = size / 2;
 #else
 #  error We only support 16-bit integer PCM
 #endif
 
-      const int32_t numFrames = numSamples / mOutputChannels;
       AlignedAudioBuffer audio(numSamples);
       if (!audio) {
         Error(MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__));
         return;
       }
 
       jni::ByteBuffer::LocalRef dest = jni::ByteBuffer::New(audio.get(), size);
       aSample->WriteToByteBuffer(dest);
 
       RefPtr<AudioData> data =
           new AudioData(0, TimeUnit::FromMicroseconds(presentationTimeUs),
-                        FramesToTimeUnit(numFrames, mOutputSampleRate),
                         std::move(audio), mOutputChannels, mOutputSampleRate);
 
       UpdateOutputStatus(std::move(data));
     }
 
     if ((flags & MediaCodec::BUFFER_FLAG_END_OF_STREAM) != 0) {
       DrainComplete();
     }
--- a/dom/media/platforms/apple/AppleATDecoder.cpp
+++ b/dom/media/platforms/apple/AppleATDecoder.cpp
@@ -296,20 +296,21 @@ MediaResult AppleATDecoder::DecodeSample
     mAudioConverter = MakeUnique<AudioConverter>(in, out);
   }
   if (mAudioConverter && mChannelLayout && mChannelLayout->IsValid()) {
     MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
     data = mAudioConverter->Process(std::move(data));
   }
 
   RefPtr<AudioData> audio = new AudioData(
-      aSample->mOffset, aSample->mTime, duration, data.Forget(), channels, rate,
+      aSample->mOffset, aSample->mTime, data.Forget(), channels, rate,
       mChannelLayout && mChannelLayout->IsValid()
           ? mChannelLayout->Map()
           : AudioConfig::ChannelLayout::UNKNOWN_MAP);
+  MOZ_DIAGNOSTIC_ASSERT(duration == audio->mDuration, "must be equal");
   mDecodedSamples.AppendElement(std::move(audio));
   return NS_OK;
 }
 
 MediaResult AppleATDecoder::GetInputAudioDescription(
     AudioStreamBasicDescription& aDesc, const nsTArray<uint8_t>& aExtraData) {
   MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
 
--- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp
@@ -237,19 +237,21 @@ MediaResult FFmpegAudioDecoder<LIBAV_VER
 
       media::TimeUnit newpts = pts + duration;
       if (!newpts.IsValid()) {
         return MediaResult(
             NS_ERROR_DOM_MEDIA_OVERFLOW_ERR,
             RESULT_DETAIL("Invalid count of accumulated audio samples"));
       }
 
-      aResults.AppendElement(new AudioData(
-          samplePosition, pts, duration, std::move(audio), numChannels,
-          samplingRate, mCodecContext->channel_layout));
+      RefPtr<AudioData> data =
+          new AudioData(samplePosition, pts, std::move(audio), numChannels,
+                        samplingRate, mCodecContext->channel_layout);
+      MOZ_DIAGNOSTIC_ASSERT(duration == data->mDuration, "must be equal");
+      aResults.AppendElement(std::move(data));
 
       pts = newpts;
 
       if (aGotFrame) {
         *aGotFrame = true;
       }
     }
     packet.data += bytesConsumed;
--- a/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFAudioMFTManager.cpp
@@ -321,19 +321,19 @@ WMFAudioMFTManager::Output(int64_t aStre
       mAudioTimeOffset + FramesToTimeUnit(mAudioFrameSum, mAudioRate);
   NS_ENSURE_TRUE(timestamp.IsValid(), E_FAIL);
 
   mAudioFrameSum += numFrames;
 
   media::TimeUnit duration = FramesToTimeUnit(numFrames, mAudioRate);
   NS_ENSURE_TRUE(duration.IsValid(), E_FAIL);
 
-  aOutData =
-      new AudioData(aStreamOffset, timestamp, duration, std::move(audioData),
-                    mAudioChannels, mAudioRate, mChannelsMap);
+  aOutData = new AudioData(aStreamOffset, timestamp, std::move(audioData),
+                           mAudioChannels, mAudioRate, mChannelsMap);
+  MOZ_DIAGNOSTIC_ASSERT(duration == aOutData->mDuration, "must be equal");
 
 #ifdef LOG_SAMPLE_DECODE
   LOG("Decoded audio sample! timestamp=%lld duration=%lld currentLength=%u",
       timestamp.ToMicroseconds(), duration.ToMicroseconds(), currentLength);
 #endif
 
   return S_OK;
 }