diff mbox series

[FFmpeg-devel,1/2] avcodec/mediacodec: fix missing crop info when use NDK MediaCodec

Message ID tencent_4753151C69CB97E61DD0A6A6ECE7DC2A9506@qq.com
State New
Headers show
Series [FFmpeg-devel,1/2] avcodec/mediacodec: fix missing crop info when use NDK MediaCodec | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Zhao Zhili Nov. 23, 2022, 4:49 p.m. UTC
From: Zhao Zhili <zhilizhao@tencent.com>

---
 libavcodec/mediacodec_wrapper.c   | 38 ++++++++++++++++++++++++++++---
 libavcodec/mediacodec_wrapper.h   | 24 +++++++++++++++++++
 libavcodec/mediacodecdec_common.c |  4 ++++
 3 files changed, 63 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
index 555058e907..193eac8da6 100644
--- a/libavcodec/mediacodec_wrapper.c
+++ b/libavcodec/mediacodec_wrapper.c
@@ -1861,12 +1861,16 @@  typedef struct FFAMediaFormatNdk {
     bool (*getSize)(AMediaFormat*, const char *name, size_t *out);
     bool (*getBuffer)(AMediaFormat*, const char *name, void** data, size_t *size);
     bool (*getString)(AMediaFormat*, const char *name, const char **out);
+    bool (*getRect)(AMediaFormat *, const char *name,
+                    int32_t *left, int32_t *top, int32_t *right, int32_t *bottom);
 
     void (*setInt32)(AMediaFormat*, const char* name, int32_t value);
     void (*setInt64)(AMediaFormat*, const char* name, int64_t value);
     void (*setFloat)(AMediaFormat*, const char* name, float value);
     void (*setString)(AMediaFormat*, const char* name, const char* value);
     void (*setBuffer)(AMediaFormat*, const char* name, const void* data, size_t size);
+    void (*setRect)(AMediaFormat *, const char *name,
+                    int32_t left, int32_t top, int32_t right, int32_t bottom);
 } FFAMediaFormatNdk;
 
 typedef struct FFAMediaCodecNdk {
@@ -1940,9 +1944,12 @@  static FFAMediaFormat *mediaformat_ndk_create(AMediaFormat *impl)
     if (!format->libmedia)
         goto error;
 
-#define GET_SYMBOL(sym) \
-    format->sym = dlsym(format->libmedia, "AMediaFormat_" #sym);    \
-    if (!format->sym)                                               \
+#define GET_OPTIONAL_SYMBOL(sym) \
+    format->sym = dlsym(format->libmedia, "AMediaFormat_" #sym);
+
+#define GET_SYMBOL(sym)         \
+    GET_OPTIONAL_SYMBOL(sym)    \
+    if (!format->sym)           \
         goto error;
 
     GET_SYMBOL(new)
@@ -1956,14 +1963,17 @@  static FFAMediaFormat *mediaformat_ndk_create(AMediaFormat *impl)
     GET_SYMBOL(getSize)
     GET_SYMBOL(getBuffer)
     GET_SYMBOL(getString)
+    GET_OPTIONAL_SYMBOL(getRect)
 
     GET_SYMBOL(setInt32)
     GET_SYMBOL(setInt64)
     GET_SYMBOL(setFloat)
     GET_SYMBOL(setString)
     GET_SYMBOL(setBuffer)
+    GET_OPTIONAL_SYMBOL(setRect)
 
 #undef GET_SYMBOL
+#undef GET_OPTIONAL_SYMBOL
 
     if (impl) {
         format->impl = impl;
@@ -2047,6 +2057,15 @@  static int mediaformat_ndk_getString(FFAMediaFormat* ctx, const char *name, cons
     return ret;
 }
 
+static int mediaformat_ndk_getRect(FFAMediaFormat *ctx, const char *name,
+                                   int32_t *left, int32_t *top, int32_t *right, int32_t *bottom)
+{
+    FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+    if (!format->getRect)
+        return AVERROR_EXTERNAL;
+    return format->getRect(format->impl, name, left, top, right, bottom);
+}
+
 static void mediaformat_ndk_setInt32(FFAMediaFormat* ctx, const char* name, int32_t value)
 {
     FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
@@ -2077,6 +2096,17 @@  static void mediaformat_ndk_setBuffer(FFAMediaFormat* ctx, const char* name, voi
     format->setBuffer(format->impl, name, data, size);
 }
 
+static void mediaformat_ndk_setRect(FFAMediaFormat *ctx, const char *name,
+                                     int32_t left, int32_t top, int32_t right, int32_t bottom)
+{
+    FFAMediaFormatNdk *format = (FFAMediaFormatNdk *)ctx;
+    if (!format->setRect) {
+        av_log(ctx, AV_LOG_WARNING, "Doesn't support setRect\n");
+        return;
+    }
+    format->setRect(format->impl, name, left, top, right, bottom);
+}
+
 static char *mediacodec_ndk_getName(FFAMediaCodec *ctx)
 {
     FFAMediaCodecNdk *codec = (FFAMediaCodecNdk *)ctx;
@@ -2433,12 +2463,14 @@  static const FFAMediaFormat media_format_ndk = {
     .getFloat = mediaformat_ndk_getFloat,
     .getBuffer = mediaformat_ndk_getBuffer,
     .getString = mediaformat_ndk_getString,
+    .getRect = mediaformat_ndk_getRect,
 
     .setInt32 = mediaformat_ndk_setInt32,
     .setInt64 = mediaformat_ndk_setInt64,
     .setFloat = mediaformat_ndk_setFloat,
     .setString = mediaformat_ndk_setString,
     .setBuffer = mediaformat_ndk_setBuffer,
+    .setRect = mediaformat_ndk_setRect,
 };
 
 static const FFAMediaCodec media_codec_ndk = {
diff --git a/libavcodec/mediacodec_wrapper.h b/libavcodec/mediacodec_wrapper.h
index f15ad66d83..1b81e6db84 100644
--- a/libavcodec/mediacodec_wrapper.h
+++ b/libavcodec/mediacodec_wrapper.h
@@ -73,12 +73,18 @@  struct FFAMediaFormat {
     int (*getFloat)(FFAMediaFormat* format, const char *name, float *out);
     int (*getBuffer)(FFAMediaFormat* format, const char *name, void** data, size_t *size);
     int (*getString)(FFAMediaFormat* format, const char *name, const char **out);
+    // NDK only, introduced in API level 28
+    int (*getRect)(FFAMediaFormat *, const char *name,
+                   int32_t *left, int32_t *top, int32_t *right, int32_t *bottom);
 
     void (*setInt32)(FFAMediaFormat* format, const char* name, int32_t value);
     void (*setInt64)(FFAMediaFormat* format, const char* name, int64_t value);
     void (*setFloat)(FFAMediaFormat* format, const char* name, float value);
     void (*setString)(FFAMediaFormat* format, const char* name, const char* value);
     void (*setBuffer)(FFAMediaFormat* format, const char* name, void* data, size_t size);
+    // NDK only, introduced in API level 28
+    void (*setRect)(FFAMediaFormat*, const char* name,
+                    int32_t left, int32_t top, int32_t right, int32_t bottom);
 };
 
 FFAMediaFormat *ff_AMediaFormat_new(int ndk);
@@ -118,6 +124,14 @@  static inline int ff_AMediaFormat_getString(FFAMediaFormat* format, const char *
     return format->getString(format, name, out);
 }
 
+static inline int ff_AMediaFormat_getRect(FFAMediaFormat *format, const char *name,
+                                          int32_t *left, int32_t *top, int32_t *right, int32_t *bottom)
+{
+    if (!format->getRect)
+        return AVERROR_EXTERNAL;
+    return format->getRect(format, name, left, top, right, bottom);
+}
+
 static inline void ff_AMediaFormat_setInt32(FFAMediaFormat* format, const char* name, int32_t value)
 {
     format->setInt32(format, name, value);
@@ -143,6 +157,16 @@  static inline void ff_AMediaFormat_setBuffer(FFAMediaFormat* format, const char*
     format->setBuffer(format, name, data, size);
 }
 
+static inline void ff_AMediaFormat_setRect(FFAMediaFormat* format, const char* name,
+                                           int32_t left, int32_t top, int32_t right, int32_t bottom)
+{
+    if (!format->setRect) {
+        av_log(format, AV_LOG_WARNING, "Doesn't support setRect\n");
+        return;
+    }
+    format->setRect(format, name, left, top, right, bottom);
+}
+
 typedef struct FFAMediaCodecCryptoInfo FFAMediaCodecCryptoInfo;
 
 struct FFAMediaCodecBufferInfo {
diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c
index 80089439ea..03bee11918 100644
--- a/libavcodec/mediacodecdec_common.c
+++ b/libavcodec/mediacodecdec_common.c
@@ -486,6 +486,10 @@  static int mediacodec_dec_parse_format(AVCodecContext *avctx, MediaCodecDecConte
     AMEDIAFORMAT_GET_INT32(s->crop_left,   "crop-left",   0);
     AMEDIAFORMAT_GET_INT32(s->crop_right,  "crop-right",  0);
 
+    // Try "crop" for NDK
+    if (!(s->crop_right && s->crop_bottom) && s->use_ndk_codec)
+        ff_AMediaFormat_getRect(s->format, "crop", &s->crop_left, &s->crop_top, &s->crop_right, &s->crop_bottom);
+
     if (s->crop_right && s->crop_bottom) {
         width = s->crop_right + 1 - s->crop_left;
         height = s->crop_bottom + 1 - s->crop_top;