Bug 901633 - Part 8 - Use our new generic packetizer in the MediaPipeline so that we can packetize stereo easily. r=jesup
authorPaul Adenot <paul@paul.cx>
Tue, 11 Aug 2015 13:49:29 +0200
changeset 260330 4547ae1e73ee9df217c1b8c007820bf4fb1bf792
parent 260329 f13da3f6b4943b43dfab477af39f8c01fff26bc5
child 260331 142737374b1c9f955981bba3e2c2b00d0d026558
push id29307
push userryanvm@gmail.com
push dateWed, 02 Sep 2015 01:01:53 +0000
treeherdermozilla-central@e2eb0442ece9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs901633
milestone43.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 901633 - Part 8 - Use our new generic packetizer in the MediaPipeline so that we can packetize stereo easily. r=jesup
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -974,74 +974,39 @@ void MediaPipelineTransmit::PipelineList
         break;
       case AUDIO_FORMAT_SILENCE:
         PodZero(convertedSamples.get(), chunk.mDuration * outputChannels);
         break;
   }
 
   MOZ_ASSERT(!(rate%100)); // rate should be a multiple of 100
 
-  // Check if the rate has changed since the last time we came through
-  // I realize it may be overkill to check if the rate has changed, but
-  // I believe it is possible (e.g. if we change sources) and it costs us
-  // very little to handle this case
+  // Check if the rate or the number of channels has changed since the last time
+  // we came through I realize it may be overkill to check if the rate has
+  // changed, but I believe it is possible (e.g. if we change sources) and it
+  // costs us very little to handle this case
 
-  if (samplenum_10ms_ !=  rate/100) {
-    // Determine number of samples in 10 ms from the rate:
-    samplenum_10ms_ = rate/100;
-    // If we switch sample rates (e.g. if we switch codecs),
-    // we throw away what was in the sample_10ms_buffer at the old rate
-    samples_10ms_buffer_ = new int16_t[samplenum_10ms_];
-    buffer_current_ = 0;
-  }
-
-  // Vars to handle the non-sunny-day case (where the audio chunks
-  // we got are not multiples of 10ms OR there were samples left over
-  // from the last run)
-  int64_t chunk_remaining;
-  int64_t tocpy;
-  int16_t *samples_tmp = convertedSamples.get();
-
-  chunk_remaining = chunk.mDuration;
-
-  MOZ_ASSERT(chunk_remaining >= 0);
+  uint32_t audio_10ms = rate / 100;
 
-  if (buffer_current_) {
-    tocpy = std::min(chunk_remaining, samplenum_10ms_ - buffer_current_);
-    memcpy(&samples_10ms_buffer_[buffer_current_], samples_tmp, tocpy * sizeof(int16_t));
-    buffer_current_ += tocpy;
-    samples_tmp += tocpy;
-    chunk_remaining -= tocpy;
-
-    if (buffer_current_ == samplenum_10ms_) {
-      // Send out the audio buffer we just finished filling
-      conduit->SendAudioFrame(samples_10ms_buffer_, samplenum_10ms_, rate, 0);
-      buffer_current_ = 0;
-    } else {
-      // We still don't have enough data to send a buffer
-      return;
-    }
-  }
+  if (!packetizer_ ||
+      packetizer_->PacketSize() != audio_10ms ||
+      packetizer_->Channels() != outputChannels) {
+    // It's ok to drop the audio still in the packetizer here.
+    packetizer_ = new AudioPacketizer<int16_t, int16_t>(audio_10ms, outputChannels);
+   }
 
-  // Now send (more) frames if there is more than 10ms of input left
-  tocpy = (chunk_remaining / samplenum_10ms_) * samplenum_10ms_;
-  if (tocpy > 0) {
-    conduit->SendAudioFrame(samples_tmp, tocpy, rate, 0);
-    samples_tmp += tocpy;
-    chunk_remaining -= tocpy;
+  packetizer_->Input(convertedSamples, chunk.mDuration);
+
+  while (packetizer_->PacketsAvailable()) {
+    uint32_t samplesPerPacket = packetizer_->PacketSize() *
+                                packetizer_->Channels();
+    conduit->SendAudioFrame(packetizer_->Output(),
+                            samplesPerPacket ,
+                            rate, 0);
   }
-  // Copy what remains for the next run
-
-  MOZ_ASSERT(chunk_remaining < samplenum_10ms_);
-
-  if (chunk_remaining) {
-    memcpy(samples_10ms_buffer_, samples_tmp, chunk_remaining * sizeof(int16_t));
-    buffer_current_ = chunk_remaining;
-  }
-
 }
 
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
 void MediaPipelineTransmit::PipelineListener::ProcessVideoChunk(
     VideoSessionConduit* conduit,
     VideoChunk& chunk) {
   Image *img = chunk.mFrame.GetImage();
 
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.h
@@ -21,16 +21,17 @@
 #include "MediaPipelineFilter.h"
 #include "AudioSegment.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Atomics.h"
 #include "SrtpFlow.h"
 #include "databuffer.h"
 #include "runnable_utils.h"
 #include "transportflow.h"
+#include "AudioPacketizer.h"
 
 #if defined(MOZILLA_INTERNAL_API)
 #include "VideoSegment.h"
 #endif
 
 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
 
 namespace mozilla {
@@ -441,19 +442,17 @@ public:
     explicit PipelineListener(const RefPtr<MediaSessionConduit>& conduit)
       : conduit_(conduit),
         track_id_(TRACK_INVALID),
         mMutex("MediaPipelineTransmit::PipelineListener"),
         track_id_external_(TRACK_INVALID),
         active_(false),
         enabled_(false),
         direct_connect_(false),
-        samples_10ms_buffer_(nullptr),
-        buffer_current_(0),
-        samplenum_10ms_(0)
+        packetizer_(nullptr)
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
         , last_img_(-1)
 #endif // MOZILLA_INTERNAL_API
     {
     }
 
     ~PipelineListener()
     {
@@ -521,26 +520,17 @@ public:
     // active is true if there is a transport to send on
     mozilla::Atomic<bool> active_;
     // enabled is true if the media access control permits sending
     // actual content; when false you get black/silence
     mozilla::Atomic<bool> enabled_;
 
     bool direct_connect_;
 
-
-    // These vars handle breaking audio samples into exact 10ms chunks:
-    // The buffer of 10ms audio samples that we will send once full
-    // (can be carried over from one call to another).
-    nsAutoArrayPtr<int16_t> samples_10ms_buffer_;
-    // The location of the pointer within that buffer (in units of samples).
-    int64_t buffer_current_;
-    // The number of samples in a 10ms audio chunk.
-    int64_t samplenum_10ms_;
-
+    nsAutoPtr<AudioPacketizer<int16_t, int16_t>> packetizer_;
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
     int32_t last_img_; // serial number of last Image
 #endif // MOZILLA_INTERNAL_API
   };
 
  private:
   RefPtr<PipelineListener> listener_;
   DOMMediaStream *domstream_;