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 <sharp...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".