diff mbox series

[FFmpeg-devel,v2,08/12] avutil/hwcontext_mediacodec: add ANativeWindow support

Message ID tencent_CAEE5A7034B9811434CD3F8B56F59D4AE009@qq.com
State Accepted
Commit 2697f23f4e866a81ddcfca0c99a56ed14f93dc07
Headers show
Series None | expand

Commit Message

Zhao Zhili Nov. 20, 2022, 6:49 a.m. UTC
From: Zhao Zhili <zhilizhao@tencent.com>

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
---
 libavutil/hwcontext_mediacodec.c | 56 +++++++++++++++++++++++++++++++-
 libavutil/hwcontext_mediacodec.h | 11 +++++++
 libavutil/version.h              |  2 +-
 3 files changed, 67 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/libavutil/hwcontext_mediacodec.c b/libavutil/hwcontext_mediacodec.c
index b0d8993e15..bb1779d34d 100644
--- a/libavutil/hwcontext_mediacodec.c
+++ b/libavutil/hwcontext_mediacodec.c
@@ -18,12 +18,24 @@ 
 
 #include "config.h"
 
+#include <android/native_window.h>
+#include <dlfcn.h>
+#include <media/NdkMediaCodec.h>
+
 #include "buffer.h"
 #include "common.h"
 #include "hwcontext.h"
 #include "hwcontext_internal.h"
 #include "hwcontext_mediacodec.h"
 
+typedef struct MediaCodecDeviceContext {
+    AVMediaCodecDeviceContext ctx;
+
+    void *libmedia;
+    media_status_t (*create_surface)(ANativeWindow **surface);
+} MediaCodecDeviceContext;
+
+
 static int mc_device_create(AVHWDeviceContext *ctx, const char *device,
                             AVDictionary *opts, int flags)
 {
@@ -35,13 +47,55 @@  static int mc_device_create(AVHWDeviceContext *ctx, const char *device,
     return 0;
 }
 
+static int mc_device_init(AVHWDeviceContext *ctx)
+{
+    MediaCodecDeviceContext *s = ctx->hwctx;
+    AVMediaCodecDeviceContext *dev = (AVMediaCodecDeviceContext *)s;
+    ANativeWindow *native_window = NULL;
+
+    if (dev->surface)
+        return 0;
+
+    if (dev->native_window)
+        return 0;
+
+    s->libmedia = dlopen("libmediandk.so", RTLD_NOW);
+    if (!s->libmedia)
+        return AVERROR_UNKNOWN;
+
+    s->create_surface = dlsym(s->libmedia, "AMediaCodec_createPersistentInputSurface");
+    if (!s->create_surface)
+        return AVERROR_UNKNOWN;
+
+    s->create_surface(&native_window);
+    dev->native_window = native_window;
+    return 0;
+}
+
+static void mc_device_uninit(AVHWDeviceContext *ctx)
+{
+    MediaCodecDeviceContext *s = ctx->hwctx;
+    AVMediaCodecDeviceContext *dev = ctx->hwctx;
+    if (!s->libmedia)
+        return;
+
+    if (dev->native_window) {
+        ANativeWindow_release(dev->native_window);
+        dev->native_window = NULL;
+    }
+    dlclose(s->libmedia);
+    s->libmedia = NULL;
+}
+
 const HWContextType ff_hwcontext_type_mediacodec = {
     .type                 = AV_HWDEVICE_TYPE_MEDIACODEC,
     .name                 = "mediacodec",
 
-    .device_hwctx_size    = sizeof(AVMediaCodecDeviceContext),
+    .device_hwctx_size    = sizeof(MediaCodecDeviceContext),
 
     .device_create        = mc_device_create,
+    .device_init          = mc_device_init,
+    .device_uninit        = mc_device_uninit,
 
     .pix_fmts = (const enum AVPixelFormat[]){
         AV_PIX_FMT_MEDIACODEC,
diff --git a/libavutil/hwcontext_mediacodec.h b/libavutil/hwcontext_mediacodec.h
index 101a9806d5..920e17764f 100644
--- a/libavutil/hwcontext_mediacodec.h
+++ b/libavutil/hwcontext_mediacodec.h
@@ -31,6 +31,17 @@  typedef struct AVMediaCodecDeviceContext {
      * This is the default surface used by decoders on this device.
      */
     void *surface;
+
+    /**
+     * Pointer to ANativeWindow.
+     *
+     * It both surface and native_window is NULL, try to create it
+     * automatically if OS support.
+     *
+     * It can be used as output surface for decoder and input surface for
+     * encoder.
+     */
+    void *native_window;
 } AVMediaCodecDeviceContext;
 
 #endif /* AVUTIL_HWCONTEXT_MEDIACODEC_H */
diff --git a/libavutil/version.h b/libavutil/version.h
index 9b9eea2946..3b616ea489 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@ 
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  57
-#define LIBAVUTIL_VERSION_MINOR  42
+#define LIBAVUTIL_VERSION_MINOR  43
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \