Bug 1101651 - Part 1: xpcomrt version of dom media library need for standalone webrtcs. r=jesup
authorRandall Barker <rbarker@mozilla.com>
Thu, 09 Apr 2015 09:15:00 -0400
changeset 256455 2aef619be58e5a0dc04e803e0830abac176432a3
parent 256454 6f7d0ef4912a562dda8557109fb2fa981ff1dc01
child 256456 7c2a1eaed3acd9b3931266fab54b9e91d5f9698d
push id1476
push usergijskruitbosch@gmail.com
push dateFri, 10 Apr 2015 12:37:44 +0000
reviewersjesup
bugs1101651
milestone40.0a1
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']