Bug 1322650 - Make video decoding work with new SurfaceTexture API r=jolin draft
authorJames Willcox <snorp@snorp.net>
Fri, 03 Mar 2017 15:16:28 -0600
changeset 568953 3350555b14618f485392a528b719ff66e69eccc4
parent 568952 0802d4a6c34d764fd10ff4fa90af64cba04c8fa0
child 568954 92b3766da310a002adfeea3303e8eb93a21cfb33
push id56033
push userbmo:snorp@snorp.net
push dateWed, 26 Apr 2017 20:29:44 +0000
reviewersjolin
bugs1322650
milestone55.0a1
Bug 1322650 - Make video decoding work with new SurfaceTexture API r=jolin MozReview-Commit-ID: EXQ5YDSMMGL
dom/media/platforms/android/RemoteDataDecoder.cpp
mobile/android/geckoview/src/main/AndroidManifest.xml
--- a/dom/media/platforms/android/RemoteDataDecoder.cpp
+++ b/dom/media/platforms/android/RemoteDataDecoder.cpp
@@ -1,15 +1,14 @@
 /* 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 "AndroidBridge.h"
 #include "AndroidDecoderModule.h"
-#include "AndroidSurfaceTexture.h"
 #include "JavaCallbacksSupport.h"
 #include "SimpleMap.h"
 #include "GLImages.h"
 #include "MediaData.h"
 #include "MediaInfo.h"
 #include "VideoUtils.h"
 #include "VPXDecoder.h"
 
@@ -129,17 +128,17 @@ public:
       InputInfo inputInfo;
       if (!mDecoder->mInputInfos.Find(presentationTimeUs, inputInfo)
           && !isEOS) {
         return;
       }
 
       if (size > 0) {
         RefPtr<layers::Image> img = new SurfaceTextureImage(
-          mDecoder->mSurfaceTexture.get(), inputInfo.mImageSize,
+          mDecoder->mSurfaceHandle, inputInfo.mImageSize,
           gl::OriginPos::BottomLeft);
 
         RefPtr<VideoData> v = VideoData::CreateFromImage(
           inputInfo.mDisplaySize, offset, presentationTimeUs,
           TimeUnit::FromMicroseconds(inputInfo.mDurationUs),
           img, !!(flags & MediaCodec::BUFFER_FLAG_SYNC_FRAME),
           presentationTimeUs);
 
@@ -171,39 +170,34 @@ public:
                         aFormat, aDrmStubId, aTaskQueue)
     , mImageContainer(aImageContainer)
     , mConfig(aConfig)
   {
   }
 
   RefPtr<InitPromise> Init() override
   {
-    mSurfaceTexture = AndroidSurfaceTexture::Create();
-    if (!mSurfaceTexture) {
-      NS_WARNING("Failed to create SurfaceTexture for video decode\n");
-      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                          __func__);
+    jni::Object::LocalRef surf = SurfaceAllocator::AcquireSurface(mConfig.mImage.width, mConfig.mImage.height, false);
+    if (!surf) {
+      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
     }
 
-    if (!jni::IsFennec()) {
-      NS_WARNING("Remote decoding not supported in non-Fennec environment\n");
-      return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
-                                          __func__);
-    }
+    mSurfaceHandle = GeckoSurface::LocalRef(GeckoSurface::Ref::From(surf))->GetHandle();
 
     // Register native methods.
     JavaCallbacksSupport::Init();
 
     mJavaCallbacks = CodecProxy::NativeCallbacks::New();
     JavaCallbacksSupport::AttachNative(
       mJavaCallbacks, mozilla::MakeUnique<CallbacksSupport>(this));
 
+    auto surfRef = Surface::LocalRef(Surface::Ref::From(surf));
     mJavaDecoder = CodecProxy::Create(false, // false indicates to create a decoder and true denotes encoder
                                       mFormat,
-                                      mSurfaceTexture->JavaSurface(),
+                                      surfRef,
                                       mJavaCallbacks,
                                       mDrmStubId);
     if (mJavaDecoder == nullptr) {
       return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_FATAL_ERR,
                                           __func__);
     }
     mIsCodecSupportAdaptivePlayback =
       mJavaDecoder->IsAdaptivePlaybackSupported();
@@ -233,17 +227,17 @@ public:
   bool SupportDecoderRecycling() const override
   {
     return mIsCodecSupportAdaptivePlayback;
   }
 
 private:
   layers::ImageContainer* mImageContainer;
   const VideoInfo mConfig;
-  RefPtr<AndroidSurfaceTexture> mSurfaceTexture;
+  AndroidSurfaceTextureHandle mSurfaceHandle;
   SimpleMap<InputInfo> mInputInfos;
   bool mIsCodecSupportAdaptivePlayback = false;
 };
 
 class RemoteAudioDecoder : public RemoteDataDecoder
 {
 public:
   RemoteAudioDecoder(const AudioInfo& aConfig,
@@ -405,17 +399,16 @@ RemoteDataDecoder::CreateAudioDecoder(co
   return decoder.forget();
 }
 
 already_AddRefed<MediaDataDecoder>
 RemoteDataDecoder::CreateVideoDecoder(const CreateDecoderParams& aParams,
                                       const nsString& aDrmStubId,
                                       CDMProxy* aProxy)
 {
-
   const VideoInfo& config = aParams.VideoConfig();
   MediaFormat::LocalRef format;
   NS_ENSURE_SUCCESS(
     MediaFormat::CreateVideoFormat(TranslateMimeType(config.mMimeType),
                                    config.mDisplay.width,
                                    config.mDisplay.height,
                                    &format),
     nullptr);
--- a/mobile/android/geckoview/src/main/AndroidManifest.xml
+++ b/mobile/android/geckoview/src/main/AndroidManifest.xml
@@ -34,16 +34,24 @@
     <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
 
     <!-- App requires OpenGL ES 2.0 -->
     <uses-feature android:glEsVersion="0x00020000" android:required="true" />
 
     <application>
         <!-- New child services must also be added to the Fennec AndroidManifest.xml.in -->
         <service
+            android:name="org.mozilla.gecko.media.MediaManager"
+            android:enabled="true"
+            android:exported="false"
+            android:process=":media"
+            android:isolatedProcess="false">
+        </service>
+
+        <service
             android:name="org.mozilla.gecko.process.GeckoServiceChildProcess$geckomediaplugin"
             android:enabled="true"
             android:exported="false"
             android:process=":geckomediaplugin"
             android:isolatedProcess="false">
         </service>
 
         <service