Bug 991776: 1. Modify the testcase to ensure encoder will receive valid data. 2. Add logs for TrackEncoder. r=roc
authorBenjamin Chen <bechen@mozilla.com>
Mon, 07 Jul 2014 17:33:47 +0800
changeset 193063 3688d5116fd016281f61300bd9a104502d3b0397
parent 193062 ef24cd472cfb517a07ca3b5a38777b5b97e97eb2
child 193064 5e565152b0169f0dbb5fda7b0b1295a8d575d619
push id27107
push userryanvm@gmail.com
push dateWed, 09 Jul 2014 19:45:31 +0000
treeherdermozilla-central@6db315bcdb6a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs991776
milestone33.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 991776: 1. Modify the testcase to ensure encoder will receive valid data. 2. Add logs for TrackEncoder. r=roc
content/media/encoder/TrackEncoder.cpp
content/media/encoder/TrackEncoder.h
content/media/test/test_mediarecorder_record_4ch_audiocontext.html
content/media/test/test_mediarecorder_record_audiocontext.html
--- a/content/media/encoder/TrackEncoder.cpp
+++ b/content/media/encoder/TrackEncoder.cpp
@@ -1,49 +1,80 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "TrackEncoder.h"
 #include "AudioChannelFormat.h"
 #include "MediaStreamGraph.h"
+#include "prlog.h"
 #include "VideoUtils.h"
 
 #undef LOG
 #ifdef MOZ_WIDGET_GONK
 #include <android/log.h>
 #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "MediaEncoder", ## args);
 #else
 #define LOG(args, ...)
 #endif
 
 namespace mozilla {
 
+#ifdef PR_LOGGING
+PRLogModuleInfo* gTrackEncoderLog;
+#define TRACK_LOG(type, msg) PR_LOG(gTrackEncoderLog, type, msg)
+#else
+#define TRACK_LOG(type, msg)
+#endif
+
 static const int DEFAULT_CHANNELS = 1;
 static const int DEFAULT_SAMPLING_RATE = 16000;
 static const int DEFAULT_FRAME_WIDTH = 640;
 static const int DEFAULT_FRAME_HEIGHT = 480;
 static const int DEFAULT_TRACK_RATE = USECS_PER_S;
 
+TrackEncoder::TrackEncoder()
+  : mReentrantMonitor("media.TrackEncoder")
+  , mEncodingComplete(false)
+  , mEosSetInEncoder(false)
+  , mInitialized(false)
+  , mEndOfStream(false)
+  , mCanceled(false)
+#ifdef PR_LOGGING
+  , mAudioInitCounter(0)
+  , mVideoInitCounter(0)
+#endif
+{
+#ifdef PR_LOGGING
+  if (!gTrackEncoderLog) {
+    gTrackEncoderLog = PR_NewLogModule("TrackEncoder");
+  }
+#endif
+}
+
 void
 AudioTrackEncoder::NotifyQueuedTrackChanges(MediaStreamGraph* aGraph,
                                             TrackID aID,
                                             TrackRate aTrackRate,
                                             TrackTicks aTrackOffset,
                                             uint32_t aTrackEvents,
                                             const MediaSegment& aQueuedMedia)
 {
   if (mCanceled) {
     return;
   }
 
   const AudioSegment& audio = static_cast<const AudioSegment&>(aQueuedMedia);
 
   // Check and initialize parameters for codec encoder.
   if (!mInitialized) {
+#ifdef PR_LOGGING
+    mAudioInitCounter++;
+    TRACK_LOG(PR_LOG_DEBUG, ("Init the audio encoder %d times", mAudioInitCounter));
+#endif
     AudioSegment::ChunkIterator iter(const_cast<AudioSegment&>(audio));
     while (!iter.IsEnded()) {
       AudioChunk chunk = *iter;
 
       // The number of channels is determined by the first non-null chunk, and
       // thus the audio encoder is initialized at this time.
       if (!chunk.IsNull()) {
         nsresult rv = Init(chunk.mChannelData.Length(), aTrackRate);
@@ -153,16 +184,20 @@ VideoTrackEncoder::NotifyQueuedTrackChan
   if (mCanceled) {
     return;
   }
 
   const VideoSegment& video = static_cast<const VideoSegment&>(aQueuedMedia);
 
    // Check and initialize parameters for codec encoder.
   if (!mInitialized) {
+#ifdef PR_LOGGING
+    mVideoInitCounter++;
+    TRACK_LOG(PR_LOG_DEBUG, ("Init the video encoder %d times", mVideoInitCounter));
+#endif
     VideoSegment::ChunkIterator iter(const_cast<VideoSegment&>(video));
     while (!iter.IsEnded()) {
       VideoChunk chunk = *iter;
       if (!chunk.IsNull()) {
         gfx::IntSize imgsize = chunk.mFrame.GetImage()->GetSize();
         gfxIntSize intrinsicSize = chunk.mFrame.GetIntrinsicSize();
 #ifdef MOZ_WIDGET_GONK
         // Block the video frames come from video source.
--- a/content/media/encoder/TrackEncoder.h
+++ b/content/media/encoder/TrackEncoder.h
@@ -26,24 +26,17 @@ class MediaStreamGraph;
  * NotifyQueuedTrackChanges is called on subclasses of this class from the
  * MediaStreamGraph thread, and AppendAudioSegment/AppendVideoSegment is then
  * called to store media data in the TrackEncoder. Later on, GetEncodedTrack is
  * called on MediaEncoder's thread to encode and retrieve the encoded data.
  */
 class TrackEncoder
 {
 public:
-  TrackEncoder()
-    : mReentrantMonitor("media.TrackEncoder")
-    , mEncodingComplete(false)
-    , mEosSetInEncoder(false)
-    , mInitialized(false)
-    , mEndOfStream(false)
-    , mCanceled(false)
-  {}
+  TrackEncoder();
 
   virtual ~TrackEncoder() {}
 
   /**
    * Notified by the same callbcak of MediaEncoder when it has received a track
    * change from MediaStreamGraph. Called on the MediaStreamGraph thread.
    */
   virtual void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
@@ -126,16 +119,22 @@ protected:
    */
   bool mEndOfStream;
 
   /**
    * True if a cancellation of encoding is sent from MediaEncoder, protected by
    * mReentrantMonitor.
    */
   bool mCanceled;
+
+#ifdef PR_LOGGING
+  // How many times we have tried to initialize the encoder.
+  uint32_t mAudioInitCounter;
+  uint32_t mVideoInitCounter;
+#endif
 };
 
 class AudioTrackEncoder : public TrackEncoder
 {
 public:
   AudioTrackEncoder()
     : TrackEncoder()
     , mChannels(0)
--- a/content/media/test/test_mediarecorder_record_4ch_audiocontext.html
+++ b/content/media/test/test_mediarecorder_record_4ch_audiocontext.html
@@ -16,16 +16,17 @@ function startTest() {
   for (var i = 0; i < 80920; ++i) {
     for(var j = 0; j < 4; ++j) {
       buffer.getChannelData(j)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate);
     }
   }
 
   var source = context.createBufferSource();
   source.buffer = buffer;
+  source.loop = true;
   var dest = context.createMediaStreamDestination();
   var stopTriggered = false;
   var onstopTriggered = false;
   dest.channelCount = 4;
   var expectedMimeType = 'audio/ogg';
   var totalBlobSize = 0;
   source.channelCountMode = 'explicit';
   source.connect(dest);
--- a/content/media/test/test_mediarecorder_record_audiocontext.html
+++ b/content/media/test/test_mediarecorder_record_audiocontext.html
@@ -15,16 +15,17 @@ function startTest() {
   var hasonstop = false;
   var buffer = context.createBuffer(1, 80920, context.sampleRate);
   for (var i = 0; i < 80920; ++i) {
     buffer.getChannelData(0)[i] = Math.sin(1000 * 2 * Math.PI * i / context.sampleRate);
   }
 
   var source = context.createBufferSource();
   source.buffer = buffer;
+  source.loop = true;
 
   var dest = context.createMediaStreamDestination();
   source.connect(dest);
   var elem = document.createElement('audio');
   elem.mozSrcObject = dest.stream;
   mMediaStream = dest.stream;
   source.start(0);
   elem.play();