Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/2] lavc/mediacodecenc: Probe supported pixel formats
@ 2023-01-06 15:42 Tomas Härdin
  2023-01-06 15:43 ` [FFmpeg-devel] [PATCH 2/2] lavc/mediacodecenc: Probe actually supported color formats using JNI Tomas Härdin
  2023-01-06 18:03 ` [FFmpeg-devel] [PATCH 1/2] lavc/mediacodecenc: Probe supported pixel formats Zhao Zhili
  0 siblings, 2 replies; 6+ messages in thread
From: Tomas Härdin @ 2023-01-06 15:42 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0001-lavc-mediacodecenc-Probe-supported-pixel-formats.patch --]
[-- Type: text/x-patch, Size: 6063 bytes --]

From eb6d090967b8ed7ea0ee0651a1f557633fa23517 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= <git@haerdin.se>
Date: Thu, 22 Dec 2022 13:29:58 +0100
Subject: [PATCH 1/2] lavc/mediacodecenc: Probe supported pixel formats

For each entry in color_formats[] an encoder is configured and opened.
If this succeeds then the corresponding pixel format is added to probed_pix_fmts[].

This patch has been released by Epic Games' legal department.
---
 libavcodec/mediacodecenc.c | 76 ++++++++++++++++++++++++++++++++++----
 1 file changed, 68 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c
index 4c1809093c..fd90d41625 100644
--- a/libavcodec/mediacodecenc.c
+++ b/libavcodec/mediacodecenc.c
@@ -2,6 +2,7 @@
  * Android MediaCodec encoders
  *
  * Copyright (c) 2022 Zhao Zhili <zhilizhao@tencent.com>
+ * Modifications by Epic Games, Inc., 2022.
  *
  * This file is part of FFmpeg.
  *
@@ -89,12 +90,8 @@ static const struct {
     { COLOR_FormatSurface,              AV_PIX_FMT_MEDIACODEC },
 };
 
-static const enum AVPixelFormat avc_pix_fmts[] = {
-    AV_PIX_FMT_MEDIACODEC,
-    AV_PIX_FMT_YUV420P,
-    AV_PIX_FMT_NV12,
-    AV_PIX_FMT_NONE
-};
+// filled in by mediacodec_init_static_data()
+static enum AVPixelFormat probed_pix_fmts[FF_ARRAY_ELEMS(color_formats)+1];
 
 static void mediacodec_output_format(AVCodecContext *avctx)
 {
@@ -534,6 +531,69 @@ static av_cold int mediacodec_close(AVCodecContext *avctx)
     return 0;
 }
 
+static av_cold void mediacodec_init_static_data(FFCodec *ffcodec)
+{
+    const char *codec_mime = ffcodec->p.id == AV_CODEC_ID_H264 ? "video/avc" : "video/hevc";
+    FFAMediaCodec *codec;
+    int num_pix_fmts = 0;
+    int use_ndk_codec = !av_jni_get_java_vm(NULL);
+
+    if (!(codec = ff_AMediaCodec_createEncoderByType(codec_mime, use_ndk_codec))) {
+        av_log(NULL, AV_LOG_ERROR, "Failed to create encoder for type %s\n", codec_mime);
+        return;
+    }
+
+    for (int i = 0; i < FF_ARRAY_ELEMS(color_formats); i++) {
+        if (color_formats[i].pix_fmt == AV_PIX_FMT_MEDIACODEC) {
+            // assumme AV_PIX_FMT_MEDIACODEC always works
+            // we don't have a context at this point with which to test it
+            probed_pix_fmts[num_pix_fmts++] = color_formats[i].pix_fmt;
+        } else {
+            FFAMediaFormat *format;
+            int ret;
+
+            if (!(format = ff_AMediaFormat_new(use_ndk_codec))) {
+                av_log(NULL, AV_LOG_ERROR, "Failed to create media format\n");
+                ff_AMediaCodec_delete(codec);
+                continue;
+            }
+
+            ff_AMediaFormat_setString(format, "mime", codec_mime);
+            ff_AMediaFormat_setInt32(format, "width", 1280);
+            ff_AMediaFormat_setInt32(format, "height", 720);
+            ff_AMediaFormat_setInt32(format, "color-format", color_formats[i].color_format);
+            ff_AMediaFormat_setInt32(format, "bitrate", 1000000);
+            ff_AMediaFormat_setInt32(format, "bitrate-mode", BITRATE_MODE_VBR);
+            ff_AMediaFormat_setInt32(format, "frame-rate", 30);
+            ff_AMediaFormat_setInt32(format, "i-frame-interval", 1);
+
+            // no need to set profile, level or number of B-frames it seems
+            ret = ff_AMediaCodec_getConfigureFlagEncode(codec);
+            ret = ff_AMediaCodec_configure(codec, format, NULL, NULL, ret);
+            if (ret) {
+                av_log(NULL, AV_LOG_ERROR, "MediaCodec configure failed, %s\n", av_err2str(ret));
+                goto bailout;
+            }
+
+            ret = ff_AMediaCodec_start(codec);
+            if (ret) {
+                av_log(NULL, AV_LOG_ERROR, "MediaCodec failed to start, %s\n", av_err2str(ret));
+                goto bailout;
+            }
+            ff_AMediaCodec_stop(codec);
+
+            probed_pix_fmts[num_pix_fmts++] = color_formats[i].pix_fmt;
+        bailout:
+            // format is never NULL here
+            ff_AMediaFormat_delete(format);
+        }
+    }
+
+    probed_pix_fmts[num_pix_fmts] = AV_PIX_FMT_NONE;
+    ffcodec->p.pix_fmts = probed_pix_fmts;
+    ff_AMediaCodec_delete(codec);
+}
+
 static const AVCodecHWConfigInternal *const mediacodec_hw_configs[] = {
     &(const AVCodecHWConfigInternal) {
         .public          = {
@@ -579,7 +639,7 @@ static const AVClass name ## _mediacodec_class = {  \
 
 #define DECLARE_MEDIACODEC_ENCODER(short_name, long_name, codec_id)     \
 MEDIACODEC_ENCODER_CLASS(short_name)                                    \
-const FFCodec ff_ ## short_name ## _mediacodec_encoder = {              \
+FFCodec ff_ ## short_name ## _mediacodec_encoder = {              \
     .p.name           = #short_name "_mediacodec",                      \
     CODEC_LONG_NAME(long_name " Android MediaCodec encoder"),           \
     .p.type           = AVMEDIA_TYPE_VIDEO,                             \
@@ -587,7 +647,6 @@ const FFCodec ff_ ## short_name ## _mediacodec_encoder = {              \
     .p.capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY           \
                         | AV_CODEC_CAP_HARDWARE,                        \
     .priv_data_size   = sizeof(MediaCodecEncContext),                   \
-    .p.pix_fmts       = avc_pix_fmts,                                   \
     .init             = mediacodec_init,                                \
     FF_CODEC_RECEIVE_PACKET_CB(mediacodec_encode),                      \
     .close            = mediacodec_close,                               \
@@ -595,6 +654,7 @@ const FFCodec ff_ ## short_name ## _mediacodec_encoder = {              \
     .caps_internal    = FF_CODEC_CAP_INIT_CLEANUP,                      \
     .p.wrapper_name = "mediacodec",                                     \
     .hw_configs     = mediacodec_hw_configs,                            \
+    .init_static_data = mediacodec_init_static_data,                    \
 };                                                                      \
 
 #if CONFIG_H264_MEDIACODEC_ENCODER
-- 
2.30.2


[-- Attachment #3: Type: text/plain, Size: 251 bytes --]

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-01-09 12:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-06 15:42 [FFmpeg-devel] [PATCH 1/2] lavc/mediacodecenc: Probe supported pixel formats Tomas Härdin
2023-01-06 15:43 ` [FFmpeg-devel] [PATCH 2/2] lavc/mediacodecenc: Probe actually supported color formats using JNI Tomas Härdin
2023-01-06 18:03 ` [FFmpeg-devel] [PATCH 1/2] lavc/mediacodecenc: Probe supported pixel formats Zhao Zhili
2023-01-06 18:21   ` Tomas Härdin
2023-01-07  5:02     ` Zhao Zhili
2023-01-09 12:27       ` Tomas Härdin

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git