[FFmpeg-devel] [PATCH] avcodec/h264_metadata: add change pic_order_cnt_type option

sharpbai sharpbai at gmail.com
Sat Mar 20 10:09:55 EET 2021


Some encoder set pic_order_cnt_type=0 when not using bframe,
such as h264_videotoolbox. It may cause that some hardware decoder
delays output frames (buffer up to 18frames), such as MediaCodec
decoder before Android 11.

Setting pic_order_cnt_type=2 indicates that the picture order could not
be reversed, it will minimize the decoding delay on some decoder
implementations.

Signed-off-by: sharpbai <sharpbai at gmail.com>
---
 libavcodec/cbs_h264.h                 |  1 +
 libavcodec/cbs_h264_syntax_template.c | 16 ++++++++++++++++
 libavcodec/h264_metadata_bsf.c        |  9 +++++++++
 3 files changed, 26 insertions(+)

diff --git a/libavcodec/cbs_h264.h b/libavcodec/cbs_h264.h
index 9f7c2a0d30..00fe5178ea 100644
--- a/libavcodec/cbs_h264.h
+++ b/libavcodec/cbs_h264.h
@@ -136,6 +136,7 @@ typedef struct H264RawSPS {
 
     uint8_t log2_max_frame_num_minus4;
     uint8_t pic_order_cnt_type;
+    uint8_t pic_order_cnt_type_write;
     uint8_t log2_max_pic_order_cnt_lsb_minus4;
     uint8_t delta_pic_order_always_zero_flag;
     int32_t offset_for_non_ref_pic;
diff --git a/libavcodec/cbs_h264_syntax_template.c b/libavcodec/cbs_h264_syntax_template.c
index b65460996b..4a8a8442dd 100644
--- a/libavcodec/cbs_h264_syntax_template.c
+++ b/libavcodec/cbs_h264_syntax_template.c
@@ -324,9 +324,17 @@ static int FUNC(sps)(CodedBitstreamContext *ctx, RWContext *rw,
     }
 
     ue(log2_max_frame_num_minus4, 0, 12);
+    #ifdef READ
     ue(pic_order_cnt_type, 0, 2);
+    #else
+    ue(pic_order_cnt_type_write, 0, 2);
+    #endif
 
+    #ifdef READ
     if (current->pic_order_cnt_type == 0) {
+    #else
+    if (current->pic_order_cnt_type_write == 0) {
+    #endif
         ue(log2_max_pic_order_cnt_lsb_minus4, 0, 12);
     } else if (current->pic_order_cnt_type == 1) {
         flag(delta_pic_order_always_zero_flag);
@@ -1265,13 +1273,21 @@ static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
     if (idr_pic_flag)
         ue(idr_pic_id, 0, 65535);
 
+    #ifdef READ
     if (sps->pic_order_cnt_type == 0) {
+    #else
+    if (sps->pic_order_cnt_type_write == 0) {
+    #endif
         ub(sps->log2_max_pic_order_cnt_lsb_minus4 + 4, pic_order_cnt_lsb);
         if (pps->bottom_field_pic_order_in_frame_present_flag &&
             !current->field_pic_flag)
             se(delta_pic_order_cnt_bottom, INT32_MIN + 1, INT32_MAX);
 
+    #ifdef READ
     } else if (sps->pic_order_cnt_type == 1) {
+    #else
+    } else if (sps->pic_order_cnt_type_write == 1) {
+    #endif
         if (!sps->delta_pic_order_always_zero_flag) {
             se(delta_pic_order_cnt[0], INT32_MIN + 1, INT32_MAX);
             if (pps->bottom_field_pic_order_in_frame_present_flag &&
diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index cef054bd65..c21e477841 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -59,6 +59,7 @@ typedef struct H264MetadataContext {
     AVRational sample_aspect_ratio;
 
     int overscan_appropriate_flag;
+    int pic_order_cnt_type;
 
     int video_format;
     int video_full_range_flag;
@@ -95,6 +96,11 @@ static int h264_metadata_update_sps(AVBSFContext *bsf,
     int need_vui = 0;
     int crop_unit_x, crop_unit_y;
 
+    if (ctx->pic_order_cnt_type != -1) {
+        sps->pic_order_cnt_type_write = ctx->pic_order_cnt_type;
+    } else {
+        sps->pic_order_cnt_type_write = sps->pic_order_cnt_type;
+    }
     if (ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) {
         // Table E-1.
         static const AVRational sar_idc[] = {
@@ -689,6 +695,9 @@ static const AVOption h264_metadata_options[] = {
         OFFSET(overscan_appropriate_flag), AV_OPT_TYPE_INT,
         { .i64 = -1 }, -1, 1, FLAGS },
 
+    { "pic_order_cnt_type", "Set pic_order_cnt_type",
+        OFFSET(pic_order_cnt_type), AV_OPT_TYPE_INT,
+        { .i64 = -1 }, -1, 2, FLAGS },
     { "video_format", "Set video format (table E-2)",
         OFFSET(video_format), AV_OPT_TYPE_INT,
         { .i64 = -1 }, -1, 7, FLAGS},
-- 
2.31.0



More information about the ffmpeg-devel mailing list