123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- From 7323bd68c1b34e9298ea557ff7a3e1883b653957 Mon Sep 17 00:00:00 2001
- From: 21pages <sunboeasy@gmail.com>
- Date: Tue, 10 Dec 2024 14:28:16 +0800
- Subject: [PATCH 4/5] mediacodec changing bitrate
- Signed-off-by: 21pages <sunboeasy@gmail.com>
- ---
- libavcodec/mediacodec_wrapper.c | 98 +++++++++++++++++++++++++++++++++
- libavcodec/mediacodec_wrapper.h | 7 +++
- libavcodec/mediacodecenc.c | 18 ++++++
- 3 files changed, 123 insertions(+)
- diff --git a/libavcodec/mediacodec_wrapper.c b/libavcodec/mediacodec_wrapper.c
- index 96c886666a..06b8504304 100644
- --- a/libavcodec/mediacodec_wrapper.c
- +++ b/libavcodec/mediacodec_wrapper.c
- @@ -35,6 +35,8 @@
- #include "ffjni.h"
- #include "mediacodec_wrapper.h"
-
- +#define PARAMETER_KEY_VIDEO_BITRATE "video-bitrate"
- +
- struct JNIAMediaCodecListFields {
-
- jclass mediacodec_list_class;
- @@ -195,6 +197,8 @@ struct JNIAMediaCodecFields {
- jmethodID set_input_surface_id;
- jmethodID signal_end_of_input_stream_id;
-
- + jmethodID set_parameters_id;
- +
- jclass mediainfo_class;
-
- jmethodID init_id;
- @@ -248,6 +252,8 @@ static const struct FFJniField jni_amediacodec_mapping[] = {
- { "android/media/MediaCodec", "setInputSurface", "(Landroid/view/Surface;)V", FF_JNI_METHOD, OFFSET(set_input_surface_id), 0 },
- { "android/media/MediaCodec", "signalEndOfInputStream", "()V", FF_JNI_METHOD, OFFSET(signal_end_of_input_stream_id), 0 },
-
- + { "android/media/MediaCodec", "setParameters", "(Landroid/os/Bundle;)V", FF_JNI_METHOD, OFFSET(set_parameters_id), 0 },
- +
- { "android/media/MediaCodec$BufferInfo", NULL, NULL, FF_JNI_CLASS, OFFSET(mediainfo_class), 1 },
-
- { "android/media/MediaCodec.BufferInfo", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
- @@ -292,6 +298,24 @@ typedef struct FFAMediaCodecJni {
-
- static const FFAMediaCodec media_codec_jni;
-
- +struct JNIABundleFields
- +{
- + jclass bundle_class;
- + jmethodID init_id;
- + jmethodID put_int_id;
- +};
- +
- +#define OFFSET(x) offsetof(struct JNIABundleFields, x)
- +static const struct FFJniField jni_abundle_mapping[] = {
- + { "android/os/Bundle", NULL, NULL, FF_JNI_CLASS, OFFSET(bundle_class), 1 },
- +
- + { "android/os/Bundle", "<init>", "()V", FF_JNI_METHOD, OFFSET(init_id), 1 },
- + { "android/os/Bundle", "putInt", "(Ljava/lang/String;I)V", FF_JNI_METHOD, OFFSET(put_int_id), 1 },
- +
- + { NULL }
- +};
- +#undef OFFSET
- +
- #define JNI_GET_ENV_OR_RETURN(env, log_ctx, ret) do { \
- (env) = ff_jni_get_env(log_ctx); \
- if (!(env)) { \
- @@ -1762,6 +1786,70 @@ static int mediacodec_jni_signalEndOfInputStream(FFAMediaCodec *ctx)
- return 0;
- }
-
- +
- +static int mediacodec_jni_setParameter(FFAMediaCodec *ctx, const char* name, int value)
- +{
- + JNIEnv *env = NULL;
- + struct JNIABundleFields jfields = { 0 };
- + jobject object = NULL;
- + jstring key = NULL;
- + FFAMediaCodecJni *codec = (FFAMediaCodecJni *)ctx;
- + void *log_ctx = codec;
- + int ret = -1;
- +
- + JNI_GET_ENV_OR_RETURN(env, codec, AVERROR_EXTERNAL);
- +
- + if (ff_jni_init_jfields(env, &jfields, jni_abundle_mapping, 0, log_ctx) < 0) {
- + av_log(log_ctx, AV_LOG_ERROR, "Failed to init jfields\n");
- + goto fail;
- + }
- +
- + object = (*env)->NewObject(env, jfields.bundle_class, jfields.init_id);
- + if (!object) {
- + av_log(log_ctx, AV_LOG_ERROR, "Failed to create bundle object\n");
- + goto fail;
- + }
- +
- + key = ff_jni_utf_chars_to_jstring(env, name, log_ctx);
- + if (!key) {
- + av_log(log_ctx, AV_LOG_ERROR, "Failed to convert key to jstring\n");
- + goto fail;
- + }
- +
- + (*env)->CallVoidMethod(env, object, jfields.put_int_id, key, value);
- + if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
- + goto fail;
- + }
- +
- + if (!codec->jfields.set_parameters_id) {
- + av_log(log_ctx, AV_LOG_ERROR, "System doesn't support setParameters\n");
- + goto fail;
- + }
- +
- + (*env)->CallVoidMethod(env, codec->object, codec->jfields.set_parameters_id, object);
- + if (ff_jni_exception_check(env, 1, log_ctx) < 0) {
- + goto fail;
- + }
- +
- + ret = 0;
- +
- +fail:
- + if (key) {
- + (*env)->DeleteLocalRef(env, key);
- + }
- + if (object) {
- + (*env)->DeleteLocalRef(env, object);
- + }
- + ff_jni_reset_jfields(env, &jfields, jni_abundle_mapping, 0, log_ctx);
- +
- + return ret;
- +}
- +
- +static int mediacodec_jni_setDynamicBitrate(FFAMediaCodec *ctx, int bitrate)
- +{
- + return mediacodec_jni_setParameter(ctx, PARAMETER_KEY_VIDEO_BITRATE, bitrate);
- +}
- +
- static const FFAMediaFormat media_format_jni = {
- .class = &amediaformat_class,
-
- @@ -1821,6 +1909,8 @@ static const FFAMediaCodec media_codec_jni = {
- .getConfigureFlagEncode = mediacodec_jni_getConfigureFlagEncode,
- .cleanOutputBuffers = mediacodec_jni_cleanOutputBuffers,
- .signalEndOfInputStream = mediacodec_jni_signalEndOfInputStream,
- +
- + .setDynamicBitrate = mediacodec_jni_setDynamicBitrate,
- };
-
- typedef struct FFAMediaFormatNdk {
- @@ -2335,6 +2425,12 @@ static int mediacodec_ndk_signalEndOfInputStream(FFAMediaCodec *ctx)
- return 0;
- }
-
- +static int mediacodec_ndk_setDynamicBitrate(FFAMediaCodec *ctx, int bitrate)
- +{
- + av_log(ctx, AV_LOG_ERROR, "ndk setDynamicBitrate unavailable\n");
- + return -1;
- +}
- +
- static const FFAMediaFormat media_format_ndk = {
- .class = &amediaformat_ndk_class,
-
- @@ -2396,6 +2492,8 @@ static const FFAMediaCodec media_codec_ndk = {
- .getConfigureFlagEncode = mediacodec_ndk_getConfigureFlagEncode,
- .cleanOutputBuffers = mediacodec_ndk_cleanOutputBuffers,
- .signalEndOfInputStream = mediacodec_ndk_signalEndOfInputStream,
- +
- + .setDynamicBitrate = mediacodec_ndk_setDynamicBitrate,
- };
-
- FFAMediaFormat *ff_AMediaFormat_new(int ndk)
- diff --git a/libavcodec/mediacodec_wrapper.h b/libavcodec/mediacodec_wrapper.h
- index 11a4260497..86c64556ad 100644
- --- a/libavcodec/mediacodec_wrapper.h
- +++ b/libavcodec/mediacodec_wrapper.h
- @@ -219,6 +219,8 @@ struct FFAMediaCodec {
-
- // For encoder with FFANativeWindow as input.
- int (*signalEndOfInputStream)(FFAMediaCodec *);
- +
- + int (*setDynamicBitrate)(FFAMediaCodec *codec, int bitrate);
- };
-
- static inline char *ff_AMediaCodec_getName(FFAMediaCodec *codec)
- @@ -343,6 +345,11 @@ static inline int ff_AMediaCodec_signalEndOfInputStream(FFAMediaCodec *codec)
- return codec->signalEndOfInputStream(codec);
- }
-
- +static inline int ff_AMediaCodec_setDynamicBitrate(FFAMediaCodec *codec, int bitrate)
- +{
- + return codec->setDynamicBitrate(codec, bitrate);
- +}
- +
- int ff_Build_SDK_INT(AVCodecContext *avctx);
-
- enum FFAMediaFormatColorRange {
- diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c
- index 6ca3968a24..221f7360f4 100644
- --- a/libavcodec/mediacodecenc.c
- +++ b/libavcodec/mediacodecenc.c
- @@ -76,6 +76,8 @@ typedef struct MediaCodecEncContext {
- int level;
- int pts_as_dts;
- int extract_extradata;
- +
- + int last_bit_rate;
- } MediaCodecEncContext;
-
- enum {
- @@ -193,6 +195,8 @@ static av_cold int mediacodec_init(AVCodecContext *avctx)
- int ret;
- int gop;
-
- + s->last_bit_rate = avctx->bit_rate;
- +
- if (s->use_ndk_codec < 0)
- s->use_ndk_codec = !av_jni_get_java_vm(avctx);
-
- @@ -542,11 +546,25 @@ static int mediacodec_send(AVCodecContext *avctx,
- return 0;
- }
-
- +static void update_config(AVCodecContext *avctx)
- +{
- + MediaCodecEncContext *s = avctx->priv_data;
- + if (avctx->bit_rate != s->last_bit_rate) {
- + s->last_bit_rate = avctx->bit_rate;
- + if (0 != ff_AMediaCodec_setDynamicBitrate(s->codec, avctx->bit_rate)) {
- + av_log(avctx, AV_LOG_ERROR, "Failed to set bitrate to %d\n", avctx->bit_rate);
- + } else {
- + av_log(avctx, AV_LOG_INFO, "Set bitrate to %d\n", avctx->bit_rate);
- + }
- + }
- +}
- +
- static int mediacodec_encode(AVCodecContext *avctx, AVPacket *pkt)
- {
- MediaCodecEncContext *s = avctx->priv_data;
- int ret;
-
- + update_config(avctx);
- // Return on three case:
- // 1. Serious error
- // 2. Got a packet success
- --
- 2.43.0.windows.1
|