diff mbox series

[FFmpeg-devel] avcodec/mediacodecenc: set quality in cq mode

Message ID tencent_2D9ADA40509A7D9F72ABFC4ED370242DBD08@qq.com
State Accepted
Commit 287e22f745c0b7290ce1e80fc7cd161b41ca6997
Headers show
Series [FFmpeg-devel] avcodec/mediacodecenc: set quality in cq mode | 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 Dec. 17, 2023, 12:50 p.m. UTC
From: Zhao Zhili <zhilizhao@tencent.com>

From AOSP doc, these values are device and codec specific, but lower
values generally result in more efficient (smaller-sized) encoding.

For example, global_quality 50 on Pixel 6 results a 1080P 30 FPS
HEVC with 3744 kb/s, while global_quality 80 results 28178 kb/s.

Fix #10689

Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
---
 libavcodec/mediacodecenc.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Matthieu Bouron Dec. 19, 2023, 10:42 a.m. UTC | #1
On Sun, Dec 17, 2023 at 1:51 PM Zhao Zhili <quinkblack@foxmail.com> wrote:
>
> From: Zhao Zhili <zhilizhao@tencent.com>
>
> From AOSP doc, these values are device and codec specific, but lower
> values generally result in more efficient (smaller-sized) encoding.
>
> For example, global_quality 50 on Pixel 6 results a 1080P 30 FPS
> HEVC with 3744 kb/s, while global_quality 80 results 28178 kb/s.
>
> Fix #10689
>
> Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
> ---
>  libavcodec/mediacodecenc.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c
> index a1ae5d5ec5..7eae542248 100644
> --- a/libavcodec/mediacodecenc.c
> +++ b/libavcodec/mediacodecenc.c
> @@ -268,8 +268,11 @@ static av_cold int mediacodec_init(AVCodecContext *avctx)
>
>      if (avctx->bit_rate)
>          ff_AMediaFormat_setInt32(format, "bitrate", avctx->bit_rate);
> -    if (s->bitrate_mode >= 0)
> +    if (s->bitrate_mode >= 0) {
>          ff_AMediaFormat_setInt32(format, "bitrate-mode", s->bitrate_mode);
> +        if (s->bitrate_mode == BITRATE_MODE_CQ && avctx->global_quality > 0)
> +            ff_AMediaFormat_setInt32(format, "quality", avctx->global_quality);
> +    }
>      // frame-rate and i-frame-interval are required to configure codec
>      if (avctx->framerate.num >= avctx->framerate.den && avctx->framerate.den > 0) {
>          s->fps = avctx->framerate.num / avctx->framerate.den;
> --
> 2.34.1
>

Does the `global_quality` value need to be checked/clamped against
`MediaCodecInfo.EncoderCapabilities.getQualityRange()` before use ?
Otherwise, LGTM.
Zhao Zhili Dec. 19, 2023, 2:16 p.m. UTC | #2
On 2023/12/19 18:42, Matthieu Bouron wrote:

> On Sun, Dec 17, 2023 at 1:51 PM Zhao Zhili <quinkblack@foxmail.com> wrote:
>> From: Zhao Zhili <zhilizhao@tencent.com>
>>
>>  From AOSP doc, these values are device and codec specific, but lower
>> values generally result in more efficient (smaller-sized) encoding.
>>
>> For example, global_quality 50 on Pixel 6 results a 1080P 30 FPS
>> HEVC with 3744 kb/s, while global_quality 80 results 28178 kb/s.
>>
>> Fix #10689
>>
>> Signed-off-by: Zhao Zhili <zhilizhao@tencent.com>
>> ---
>>   libavcodec/mediacodecenc.c | 5 ++++-
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c
>> index a1ae5d5ec5..7eae542248 100644
>> --- a/libavcodec/mediacodecenc.c
>> +++ b/libavcodec/mediacodecenc.c
>> @@ -268,8 +268,11 @@ static av_cold int mediacodec_init(AVCodecContext *avctx)
>>
>>       if (avctx->bit_rate)
>>           ff_AMediaFormat_setInt32(format, "bitrate", avctx->bit_rate);
>> -    if (s->bitrate_mode >= 0)
>> +    if (s->bitrate_mode >= 0) {
>>           ff_AMediaFormat_setInt32(format, "bitrate-mode", s->bitrate_mode);
>> +        if (s->bitrate_mode == BITRATE_MODE_CQ && avctx->global_quality > 0)
>> +            ff_AMediaFormat_setInt32(format, "quality", avctx->global_quality);
>> +    }
>>       // frame-rate and i-frame-interval are required to configure codec
>>       if (avctx->framerate.num >= avctx->framerate.den && avctx->framerate.den > 0) {
>>           s->fps = avctx->framerate.num / avctx->framerate.den;
>> --
>> 2.34.1
>>
> Does the `global_quality` value need to be checked/clamped against
> `MediaCodecInfo.EncoderCapabilities.getQualityRange()` before use ?

Thanks for the review.

Firstly, since 'quality' is device and codec specific, not only valid 
range but also the

relationship between 'quality' value and the real encoding quality (and 
bitrate), some

prerequisite knowledge(or trail and error) is required. With 
prerequisite knowledge,

check valid range is unnecessary.

Secondly, from my test the device can do clamp automatically. For 
example, on pixel 6,

set H.265 quality to 100 or 1000 get the same results (I think it's 
lossless with very high

bitrate, which should never be used except in rare case).

Last but not the least, there is no NDK API for MediaCodecInfo. I want 
to avoid complex

JNI calls unless there are a lot of gains.

> Otherwise, LGTM.
> _______________________________________________
> 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".
diff mbox series

Patch

diff --git a/libavcodec/mediacodecenc.c b/libavcodec/mediacodecenc.c
index a1ae5d5ec5..7eae542248 100644
--- a/libavcodec/mediacodecenc.c
+++ b/libavcodec/mediacodecenc.c
@@ -268,8 +268,11 @@  static av_cold int mediacodec_init(AVCodecContext *avctx)
 
     if (avctx->bit_rate)
         ff_AMediaFormat_setInt32(format, "bitrate", avctx->bit_rate);
-    if (s->bitrate_mode >= 0)
+    if (s->bitrate_mode >= 0) {
         ff_AMediaFormat_setInt32(format, "bitrate-mode", s->bitrate_mode);
+        if (s->bitrate_mode == BITRATE_MODE_CQ && avctx->global_quality > 0)
+            ff_AMediaFormat_setInt32(format, "quality", avctx->global_quality);
+    }
     // frame-rate and i-frame-interval are required to configure codec
     if (avctx->framerate.num >= avctx->framerate.den && avctx->framerate.den > 0) {
         s->fps = avctx->framerate.num / avctx->framerate.den;