Bug 1101651 - Part 1, xpcomrt version of dom media library need for standalone webrtcs. r=jesup
☠☠ backed out by 6cf9b3b2c363 ☠ ☠
authorRandall Barker <rbarker@mozilla.com>
Thu, 02 Apr 2015 12:14:15 -0700
changeset 237358 b84eb39d1b52d24607adbb88e57e61090b25ec7c
parent 237357 c7da4d4c09aa5edd5f2acdc4b35640f2fd20ac83
child 237359 d02fb013d5b764812576a606391620a887121007
push id28532
push userkwierso@gmail.com
push dateFri, 03 Apr 2015 00:18:39 +0000
treeherdermozilla-central@6177eed6d23d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup
bugs1101651
milestone40.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 1101651 - Part 1, xpcomrt version of dom media library need for standalone webrtcs. r=jesup Enable WebRTC unit tests to be built using standalone WebRTC library Includes VideoSegment and SimpleImageBuffer.
dom/media/AudioSegment.cpp
dom/media/AudioSegment.h
dom/media/SimpleImageBuffer.cpp
dom/media/SimpleImageBuffer.h
dom/media/VideoSegment.cpp
dom/media/VideoSegment.h
dom/media/moz.build
dom/media/standalone/moz.build
--- a/dom/media/AudioSegment.cpp
+++ b/dom/media/AudioSegment.cpp
@@ -194,22 +194,24 @@ AudioSegment::WriteTo(uint64_t aID, Audi
       }
     } else {
       // Assumes that a bit pattern of zeroes == 0.0f
       memset(buf.Elements() + offset, 0, aOutputChannels * frames * sizeof(AudioDataValue));
     }
 
     offset += frames * aOutputChannels;
 
+#if !defined(MOZILLA_XPCOMRT_API)
     if (!c.mTimeStamp.IsNull()) {
       TimeStamp now = TimeStamp::Now();
       // would be more efficient to c.mTimeStamp to ms on create time then pass here
       LogTime(AsyncLatencyLogger::AudioMediaStreamTrack, aID,
               (now - c.mTimeStamp).ToMilliseconds(), c.mTimeStamp);
     }
+#endif // !defined(MOZILLA_XPCOMRT_API)
   }
 
   if (offset) {
     aMixer.Mix(buf.Elements(), aOutputChannels, offset / aOutputChannels, aSampleRate);
   }
 }
 
 }
--- a/dom/media/AudioSegment.h
+++ b/dom/media/AudioSegment.h
@@ -193,30 +193,36 @@ public:
         c.mDuration = (c.mDuration * aOutRate) / aInRate;
         mDuration += c.mDuration;
         continue;
       }
       uint32_t channels = c.mChannelData.Length();
       MOZ_ASSERT(channels == segmentChannelCount);
       output.SetLength(channels);
       bufferPtrs.SetLength(channels);
+#if !defined(MOZILLA_XPCOMRT_API)
+// FIXME Bug 1126414 - XPCOMRT does not support dom::WebAudioUtils::SpeexResamplerProcess
       uint32_t inFrames = c.mDuration;
+#endif // !defined(MOZILLA_XPCOMRT_API)
       // Round up to allocate; the last frame may not be used.
       NS_ASSERTION((UINT32_MAX - aInRate + 1) / c.mDuration >= aOutRate,
                    "Dropping samples");
       uint32_t outSize = (c.mDuration * aOutRate + aInRate - 1) / aInRate;
       for (uint32_t i = 0; i < channels; i++) {
         const T* in = static_cast<const T*>(c.mChannelData[i]);
         T* out = output[i].AppendElements(outSize);
         uint32_t outFrames = outSize;
 
+#if !defined(MOZILLA_XPCOMRT_API)
+// FIXME Bug 1126414 - XPCOMRT does not support dom::WebAudioUtils::SpeexResamplerProcess
         dom::WebAudioUtils::SpeexResamplerProcess(aResampler, i,
                                                   in, &inFrames,
                                                   out, &outFrames);
         MOZ_ASSERT(inFrames == c.mDuration);
+#endif // !defined(MOZILLA_XPCOMRT_API)
         bufferPtrs[i] = out;
         output[i].SetLength(outFrames);
       }
       MOZ_ASSERT(channels > 0);
       c.mDuration = output[0].Length();
       c.mBuffer = new mozilla::SharedChannelArrayBuffer<T>(&output);
       for (uint32_t i = 0; i < channels; i++) {
         c.mChannelData[i] = bufferPtrs[i];
new file mode 100644
--- /dev/null
+++ b/dom/media/SimpleImageBuffer.cpp
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 ci et: */
+/* 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 "SimpleImageBuffer.h"
+#include "mozilla/NullPtr.h"
+
+namespace mozilla {
+
+void
+SimpleImageBuffer::SetImage(const unsigned char* frame, unsigned int size, int width, int height)
+{
+  mWidth = width;
+  mHeight = height;
+  if (!mBuffer || (size > mBufferSize)) {
+    if (mBuffer) {
+      delete[] mBuffer;
+      mBuffer = nullptr;
+    }
+    mBufferSize = size;
+    if (size > 0) {
+      mBuffer = new unsigned char[size];
+    }
+  }
+
+  if (mBuffer) {
+    if (frame && (size > 0)) {
+      memcpy((void *)mBuffer, (const void*)frame, size);
+    }
+    mSize = size;
+  }
+}
+
+void
+SimpleImageBuffer::Copy(const SimpleImageBuffer* aImage)
+{
+  if (aImage) {
+    SetImage(aImage->mBuffer, aImage->mSize, aImage->mWidth, aImage->mHeight);
+  }
+}
+
+const unsigned char*
+SimpleImageBuffer::GetImage(unsigned int* size) const
+{
+  if (size) {
+    *size = mSize;
+  }
+  return mBuffer;
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/SimpleImageBuffer.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 ci et: */
+/* 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/. */
+
+#ifndef simple_image_buffer_h
+#define simple_image_buffer_h
+
+#include "mozilla/NullPtr.h"
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+
+class SimpleImageBuffer {
+NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SimpleImageBuffer)
+public:
+  SimpleImageBuffer() : mBuffer(nullptr), mBufferSize(0),  mSize(0), mWidth(0), mHeight(0) {}
+  void SetImage(const unsigned char* frame, unsigned int size, int width, int height);
+  void Copy(const SimpleImageBuffer* aImage);
+  const unsigned char* GetImage(unsigned int* size) const;
+  void GetWidthAndHeight(int* width, int* height) const
+  {
+    if (width) {
+      *width = mWidth;
+    }
+    if (height) {
+      *height = mHeight;
+    }
+  }
+
+protected:
+  ~SimpleImageBuffer()
+  {
+    delete[] mBuffer;
+  }
+  const unsigned char* mBuffer;
+  unsigned int mBufferSize;
+  unsigned int mSize;
+  int mWidth;
+  int mHeight;
+
+private:
+  SimpleImageBuffer(const SimpleImageBuffer& aImage);
+  SimpleImageBuffer& operator=(const SimpleImageBuffer& aImage);
+};
+
+} // namespace mozilla
+
+#endif //  simple_image_buffer_h
--- a/dom/media/VideoSegment.cpp
+++ b/dom/media/VideoSegment.cpp
@@ -34,16 +34,17 @@ VideoFrame::SetNull() {
 void
 VideoFrame::TakeFrom(VideoFrame* aFrame)
 {
   mImage = aFrame->mImage.forget();
   mIntrinsicSize = aFrame->mIntrinsicSize;
   mForceBlack = aFrame->GetForceBlack();
 }
 
+#if !defined(MOZILLA_XPCOMRT_API)
 /* static */ already_AddRefed<Image>
 VideoFrame::CreateBlackImage(const gfxIntSize& aSize)
 {
   nsRefPtr<ImageContainer> container;
   nsRefPtr<Image> image;
   container = LayerManager::CreateImageContainer();
   image = container->CreateImage(ImageFormat::PLANAR_YCBCR);
   if (!image) {
@@ -78,16 +79,17 @@ VideoFrame::CreateBlackImage(const gfxIn
   data.mPicSize = gfx::IntSize(aSize.width, aSize.height);
   data.mStereoMode = StereoMode::MONO;
 
   // SetData copies data, so we can free data.
   planar->SetData(data);
 
   return image.forget();
 }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 VideoChunk::VideoChunk()
 {}
 
 VideoChunk::~VideoChunk()
 {}
 
 void
--- a/dom/media/VideoSegment.h
+++ b/dom/media/VideoSegment.h
@@ -5,27 +5,35 @@
 
 #ifndef MOZILLA_VIDEOSEGMENT_H_
 #define MOZILLA_VIDEOSEGMENT_H_
 
 #include "MediaSegment.h"
 #include "nsCOMPtr.h"
 #include "gfxPoint.h"
 #include "nsAutoPtr.h"
+#if defined(MOZILLA_XPCOMRT_API)
+#include "SimpleImageBuffer.h"
+#else
 #include "ImageContainer.h"
+#endif
 
 namespace mozilla {
 
 namespace layers {
 class Image;
 }
 
 class VideoFrame {
 public:
+#if defined(MOZILLA_XPCOMRT_API)
+  typedef mozilla::SimpleImageBuffer Image;
+#else
   typedef mozilla::layers::Image Image;
+#endif
 
   VideoFrame(already_AddRefed<Image>& aImage, const gfxIntSize& aIntrinsicSize);
   VideoFrame();
   ~VideoFrame();
 
   bool operator==(const VideoFrame& aFrame) const
   {
     return mIntrinsicSize == aFrame.mIntrinsicSize &&
@@ -39,18 +47,20 @@ public:
 
   Image* GetImage() const { return mImage; }
   void SetForceBlack(bool aForceBlack) { mForceBlack = aForceBlack; }
   bool GetForceBlack() const { return mForceBlack; }
   const gfxIntSize& GetIntrinsicSize() const { return mIntrinsicSize; }
   void SetNull();
   void TakeFrom(VideoFrame* aFrame);
 
+#if !defined(MOZILLA_XPCOMRT_API)
   // Create a planar YCbCr black image.
   static already_AddRefed<Image> CreateBlackImage(const gfxIntSize& aSize);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 protected:
   // mImage can be null to indicate "no video" (aka "empty frame"). It can
   // still have an intrinsic size in this case.
   nsRefPtr<Image> mImage;
   // The desired size to render the video frame at.
   gfxIntSize mIntrinsicSize;
   bool mForceBlack;
@@ -88,17 +98,21 @@ struct VideoChunk {
 
   StreamTime mDuration;
   VideoFrame mFrame;
   mozilla::TimeStamp mTimeStamp;
 };
 
 class VideoSegment : public MediaSegmentBase<VideoSegment, VideoChunk> {
 public:
+#if defined(MOZILLA_XPCOMRT_API)
+  typedef mozilla::SimpleImageBuffer Image;
+#else
   typedef mozilla::layers::Image Image;
+#endif
   typedef mozilla::gfx::IntSize IntSize;
 
   VideoSegment();
   ~VideoSegment();
 
   void AppendFrame(already_AddRefed<Image>&& aImage,
                    StreamTime aDuration,
                    const IntSize& aIntrinsicSize,
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -11,16 +11,17 @@ DIRS += [
     'imagecapture',
     'mediasource',
     'ogg',
     'systemservices',
     'webaudio',
     'webrtc',
     'webspeech',
     'webvtt',
+    'standalone',
 ]
 
 if CONFIG['MOZ_RAW']:
     DIRS += ['raw']
 
 if CONFIG['MOZ_WAVE']:
     DIRS += ['wave']
 
new file mode 100644
--- /dev/null
+++ b/dom/media/standalone/moz.build
@@ -0,0 +1,47 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
+    Library('media_standalone')
+
+UNIFIED_SOURCES += [
+    '../AudioChannelFormat.cpp',
+    '../AudioSegment.cpp',
+    '../SimpleImageBuffer.cpp',
+    '../VideoSegment.cpp',
+]
+
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+    UNIFIED_SOURCES += ['../systemservices/OSXRunLoopSingleton.cpp']
+
+MSVC_ENABLE_PGO = True
+
+LOCAL_INCLUDES += [
+    '/caps',
+    '/dom/base',
+    '/dom/camera',
+    '/layout/generic',
+    '/layout/xul',
+    '/netwerk/base',
+]
+
+if CONFIG['MOZ_WEBRTC']:
+    LOCAL_INCLUDES += [
+        '/media/webrtc/signaling/src/common',
+        '/media/webrtc/trunk',
+    ]
+
+DEFINES['MOZILLA_INTERNAL_API'] = True
+DEFINES['MOZILLA_XPCOMRT_API'] = True
+DEFINES['MOZILLA_EXTERNAL_LINKAGE'] = True
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+# Suppress some GCC warnings being treated as errors:
+#  - about attributes on forward declarations for types that are already
+#    defined, which complains about an important MOZ_EXPORT for android::AString
+if CONFIG['GNU_CC']:
+    CXXFLAGS += ['-Wno-error=attributes']