stagefright: allow plugin to create persistent input surface

Bug: 67591367
Change-Id: Iad90113513a19ecaefeb33c891a94265c93f59e9
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 8436591..72eff94 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -479,6 +479,13 @@
 
 // static
 sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
+    // allow plugin to create surface
+    sp<PersistentSurface> pluginSurface =
+        StagefrightPluginLoader::GetCCodecInstance()->createInputSurface();
+    if (pluginSurface != nullptr) {
+        return pluginSurface;
+    }
+
     OMXClient client;
     if (client.connect() != OK) {
         ALOGE("Failed to connect to OMX to create persistent input surface.");
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 8598a49..eaff283 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -92,7 +92,14 @@
 }
 
 std::vector<MediaCodecListBuilderBase *> GetBuilders() {
-    std::vector<MediaCodecListBuilderBase *> builders {&sOmxInfoBuilder};
+    std::vector<MediaCodecListBuilderBase *> builders;
+    // if plugin provides the input surface, we cannot use OMX video encoders.
+    // In this case, rely on plugin to provide list of OMX codecs that are usable.
+    sp<PersistentSurface> surfaceTest =
+        StagefrightPluginLoader::GetCCodecInstance()->createInputSurface();
+    if (surfaceTest == nullptr) {
+        builders.push_back(&sOmxInfoBuilder);
+    }
     builders.push_back(GetCodec2InfoBuilder());
     return builders;
 }
diff --git a/media/libstagefright/StagefrightPluginLoader.cpp b/media/libstagefright/StagefrightPluginLoader.cpp
index 7f13f87..519e870 100644
--- a/media/libstagefright/StagefrightPluginLoader.cpp
+++ b/media/libstagefright/StagefrightPluginLoader.cpp
@@ -44,6 +44,11 @@
     if (mCreateBuilder == nullptr) {
         ALOGD("Failed to find symbol: CreateBuilder (%s)", dlerror());
     }
+    mCreateInputSurface = (CodecBase::CreateInputSurfaceFunc)dlsym(
+            mLibHandle, "CreateInputSurface");
+    if (mCreateBuilder == nullptr) {
+        ALOGD("Failed to find symbol: CreateInputSurface (%s)", dlerror());
+    }
 }
 
 StagefrightPluginLoader::~StagefrightPluginLoader() {
@@ -69,6 +74,14 @@
     return mCreateBuilder();
 }
 
+PersistentSurface *StagefrightPluginLoader::createInputSurface() {
+    if (mLibHandle == nullptr || mCreateInputSurface == nullptr) {
+        ALOGD("Handle or CreateInputSurface symbol is null");
+        return nullptr;
+    }
+    return mCreateInputSurface();
+}
+
 //static
 const std::unique_ptr<StagefrightPluginLoader> &StagefrightPluginLoader::GetCCodecInstance() {
     Mutex::Autolock _l(sMutex);
diff --git a/media/libstagefright/StagefrightPluginLoader.h b/media/libstagefright/StagefrightPluginLoader.h
index 2746756..999d30c 100644
--- a/media/libstagefright/StagefrightPluginLoader.h
+++ b/media/libstagefright/StagefrightPluginLoader.h
@@ -20,6 +20,7 @@
 
 #include <media/stagefright/CodecBase.h>
 #include <media/stagefright/MediaCodecListWriter.h>
+#include <media/stagefright/PersistentSurface.h>
 #include <utils/Mutex.h>
 
 namespace android {
@@ -31,6 +32,8 @@
 
     CodecBase *createCodec();
     MediaCodecListBuilderBase *createBuilder();
+    PersistentSurface *createInputSurface();
+
 private:
     explicit StagefrightPluginLoader(const char *libPath);
 
@@ -40,6 +43,7 @@
     void *mLibHandle;
     CodecBase::CreateCodecFunc mCreateCodec;
     MediaCodecListBuilderBase::CreateBuilderFunc mCreateBuilder;
+    CodecBase::CreateInputSurfaceFunc mCreateInputSurface;
 };
 
 }  // namespace android
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index 1cbf865..ad60f46 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -223,6 +223,7 @@
     virtual void signalEndOfInputStream() = 0;
 
     typedef CodecBase *(*CreateCodecFunc)(void);
+    typedef PersistentSurface *(*CreateInputSurfaceFunc)(void);
 
 protected:
     CodecBase() = default;
diff --git a/media/libstagefright/include/media/stagefright/PersistentSurface.h b/media/libstagefright/include/media/stagefright/PersistentSurface.h
index d8b75a2..173fe91 100644
--- a/media/libstagefright/include/media/stagefright/PersistentSurface.h
+++ b/media/libstagefright/include/media/stagefright/PersistentSurface.h
@@ -18,22 +18,33 @@
 
 #define PERSISTENT_SURFACE_H_
 
-#include <gui/IGraphicBufferProducer.h>
 #include <android/IGraphicBufferSource.h>
-#include <media/stagefright/foundation/ABase.h>
 #include <binder/Parcel.h>
+#include <hidl/HidlSupport.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <media/stagefright/foundation/ABase.h>
+
+using android::hidl::base::V1_0::IBase;
 
 namespace android {
 
 struct PersistentSurface : public RefBase {
     PersistentSurface() {}
 
+    // create an OMX persistent surface
     PersistentSurface(
             const sp<IGraphicBufferProducer>& bufferProducer,
             const sp<IGraphicBufferSource>& bufferSource) :
         mBufferProducer(bufferProducer),
         mBufferSource(bufferSource) { }
 
+    // create a HIDL persistent surface
+    PersistentSurface(
+            const sp<IGraphicBufferProducer>& bufferProducer,
+            const sp<IBase>& hidlTarget) :
+        mBufferProducer(bufferProducer),
+        mHidlTarget(hidlTarget) { }
+
     sp<IGraphicBufferProducer> getBufferProducer() const {
         return mBufferProducer;
     }
@@ -42,6 +53,10 @@
         return mBufferSource;
     }
 
+    sp<IBase> getHidlTarget() const {
+        return mHidlTarget;
+    }
+
     status_t writeToParcel(Parcel *parcel) const {
         parcel->writeStrongBinder(IInterface::asBinder(mBufferProducer));
         parcel->writeStrongBinder(IInterface::asBinder(mBufferSource));
@@ -59,6 +74,7 @@
 private:
     sp<IGraphicBufferProducer> mBufferProducer;
     sp<IGraphicBufferSource> mBufferSource;
+    sp<IBase> mHidlTarget;
 
     DISALLOW_EVIL_CONSTRUCTORS(PersistentSurface);
 };