Bug 1169125 - Part 1: Allow sending any DataSourceSurface-backed image over WebRTC and fix failure cases. r=bwc
authorAndreas Pehrson <pehrsons@gmail.com>
Tue, 09 Jun 2015 13:31:22 +0800
changeset 248378 92b2503d2ee77536a31d7a264e04bf14e5c01f82
parent 248377 28701c2045b3e77758049baaa1e2d56378e6f2d7
child 248379 c3af3b1cf582abc0e171e4f87a3d0cff79f79b1a
push id28893
push userkwierso@gmail.com
push dateFri, 12 Jun 2015 00:02:58 +0000
treeherderautoland@8cf9d3e497f9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbwc
bugs1169125
milestone41.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 1169125 - Part 1: Allow sending any DataSourceSurface-backed image over WebRTC and fix failure cases. r=bwc
media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
--- a/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
+++ b/media/webrtc/signaling/src/mediapipeline/MediaPipeline.cpp
@@ -38,16 +38,17 @@
 #include "transportlayerice.h"
 #include "runnable_utils.h"
 #include "libyuv/convert.h"
 #if !defined(MOZILLA_EXTERNAL_LINKAGE)
 #include "mozilla/PeerIdentity.h"
 #endif
 #include "mozilla/gfx/Point.h"
 #include "mozilla/gfx/Types.h"
+#include "mozilla/UniquePtr.h"
 
 #include "logging.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 // Logging context
 MOZ_MTLOG_MODULE("mediapipeline")
@@ -1152,61 +1153,78 @@ void MediaPipelineTransmit::PipelineList
     // GrallocImage can have wider strides, and so in some cases
     // would encode as garbage.  If we need to encode it we'll either want to
     // modify SendVideoFrame or copy/move the data in the buffer.
 
     // OK, pass it on to the conduit
     MOZ_MTLOG(ML_DEBUG, "Sending a video frame");
     // Not much for us to do with an error
     conduit->SendVideoFrame(y, I420SIZE(width, height), width, height, mozilla::kVideoI420, 0);
-  } else if(format == ImageFormat::CAIRO_SURFACE) {
-    layers::CairoImage* rgb =
-    const_cast<layers::CairoImage *>(
-          static_cast<const layers::CairoImage *>(img));
+  } else {
+    RefPtr<gfx::SourceSurface> surf = img->GetAsSourceSurface();
+    if (!surf) {
+      MOZ_MTLOG(ML_ERROR, "Getting surface from image failed");
+      return;
+    }
 
-    gfx::IntSize size = rgb->GetSize();
+    RefPtr<gfx::DataSourceSurface> data = surf->GetDataSurface();
+    if (!data) {
+      MOZ_MTLOG(ML_ERROR, "Getting data surface from image failed");
+      return;
+    }
+
+    gfx::IntSize size = img->GetSize();
     int half_width = (size.width + 1) >> 1;
     int half_height = (size.height + 1) >> 1;
     int c_size = half_width * half_height;
     int buffer_size = YSIZE(size.width, size.height) + 2 * c_size;
     uint8* yuv = (uint8*) malloc(buffer_size); // fallible
     if (!yuv)
       return;
 
-    int cb_offset = YSIZE(size.width, size.height);
-    int cr_offset = cb_offset + c_size;
-    RefPtr<gfx::SourceSurface> tempSurf = rgb->GetAsSourceSurface();
-    RefPtr<gfx::DataSourceSurface> surf = tempSurf->GetDataSurface();
+    {
+      DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
+      if (!map.IsMapped()) {
+        MOZ_MTLOG(ML_ERROR, "Reading DataSourceSurface failed");
+        return;
+      }
 
-    switch (surf->GetFormat()) {
-      case gfx::SurfaceFormat::B8G8R8A8:
-      case gfx::SurfaceFormat::B8G8R8X8:
-        libyuv::ARGBToI420(static_cast<uint8*>(surf->GetData()), surf->Stride(),
-                           yuv, size.width,
-                           yuv + cb_offset, half_width,
-                           yuv + cr_offset, half_width,
-                           size.width, size.height);
-        break;
-      case gfx::SurfaceFormat::R5G6B5:
-        libyuv::RGB565ToI420(static_cast<uint8*>(surf->GetData()), surf->Stride(),
-                             yuv, size.width,
-                             yuv + cb_offset, half_width,
-                             yuv + cr_offset, half_width,
-                             size.width, size.height);
-        break;
-      default:
-        MOZ_MTLOG(ML_ERROR, "Unsupported RGB video format");
-        MOZ_ASSERT(PR_FALSE);
+      int rv;
+      int cb_offset = YSIZE(size.width, size.height);
+      int cr_offset = cb_offset + c_size;
+      switch (surf->GetFormat()) {
+        case gfx::SurfaceFormat::B8G8R8A8:
+        case gfx::SurfaceFormat::B8G8R8X8:
+          rv = libyuv::ARGBToI420(static_cast<uint8*>(map.GetData()),
+                                  map.GetStride(),
+                                  yuv, size.width,
+                                  yuv + cb_offset, half_width,
+                                  yuv + cr_offset, half_width,
+                                  size.width, size.height);
+          break;
+        case gfx::SurfaceFormat::R5G6B5:
+          rv = libyuv::RGB565ToI420(static_cast<uint8*>(map.GetData()),
+                                    map.GetStride(),
+                                    yuv, size.width,
+                                    yuv + cb_offset, half_width,
+                                    yuv + cr_offset, half_width,
+                                    size.width, size.height);
+          break;
+        default:
+          MOZ_MTLOG(ML_ERROR, "Unsupported RGB video format");
+          MOZ_ASSERT(PR_FALSE);
+          return;
+      }
+      if (rv != 0) {
+        MOZ_MTLOG(ML_ERROR, "RGB to I420 conversion failed");
+        return;
+      }
     }
     conduit->SendVideoFrame(yuv, buffer_size, size.width, size.height, mozilla::kVideoI420, 0);
     free(yuv);
-  } else {
-    MOZ_MTLOG(ML_ERROR, "Unsupported video format");
-    MOZ_ASSERT(PR_FALSE);
-    return;
   }
 }
 #endif
 
 nsresult MediaPipelineReceiveAudio::Init() {
   ASSERT_ON_THREAD(main_thread_);
   MOZ_MTLOG(ML_DEBUG, __FUNCTION__);