Bug 991776 - Modify the testcase to ensure encoder will receive valid data and add logs for TrackEncoder. r=roc, a=test-only
authorBenjamin Chen <bechen@mozilla.com>
Mon, 07 Jul 2014 17:33:47 +0800
changeset 208883 c927922cb9551966e0038d2d0e74479c8d10886d
parent 208882 54681c0522d06aff9df60260e97a215b6b3a4400
child 208884 4ee1eccd5cdd79f2d4a338059039b48fb960bc4d
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, test-only
bugs991776
milestone32.0a2
Bug 991776 - Modify the testcase to ensure encoder will receive valid data and add logs for TrackEncoder. r=roc, a=test-only
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';
   source.channelCountMode = 'explicit';
   source.connect(dest);
   var elem = document.createElement('audio');
--- 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();