diff options
author | Clément Bœsch <u@pkh.me> | 2016-06-18 14:04:17 +0200 |
---|---|---|
committer | Clément Bœsch <u@pkh.me> | 2016-06-18 14:04:55 +0200 |
commit | 5584f019b5ebb943cd45f848e88f9e59c03f2b41 (patch) | |
tree | 1ada491eab70f85d6df4c594a7d2a262b1735f5d /libavcodec/h264.c | |
parent | 403a53c60e7c6046467ca078ca78210312879e14 (diff) | |
parent | 728d90a0c1973661a9e73da697bf4f90c9d19577 (diff) | |
download | ffmpeg-5584f019b5ebb943cd45f848e88f9e59c03f2b41.tar.gz |
Merge commit '728d90a0c1973661a9e73da697bf4f90c9d19577'
* commit '728d90a0c1973661a9e73da697bf4f90c9d19577':
h264: decouple h264_sei from the h264 decoder
Main changes:
- SEI decoding doesn't have access to the debug flag in the codec context so a
few logging are dropped.
- naming of quincunx_sampling_flag and frame_packing_arrangement_type are kept
as they are in FFmpeg instead of respectively quincunx_subsampling and
arrangement_type used in Libav because the former match the specifications.
- don't reset the x264 build info once read in order to fix
fate-h264-lossless (change by Hendrik)
- H264Context.has_recovery_point and deprecated
AVCodecContext.dtg_active_format are set after ff_h264_sei_decode()
based on the SEI state since ff_h264_sei_decode() doesn't have access
to H264Context anymore.
- frame_packing_arrangement_type is not checked against <= 0 in
decode_postinit() since it is always read as a positive value with
get_bits(). This fixes a -Wtype-limits warning by GCC spotted by
Michael.
Side Notes:
- tested that ffprobe on the file from ticket #3652 still returns 4
keyframes
- tested that playback from ticket #3063 still works
Merged-by: Clément Bœsch <clement@stupeflix.com>
Signed-off-by: Hendrik Leppkes <h.leppkes@gmail.com>
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 93 |
1 files changed, 52 insertions, 41 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 795e5999cf..831d91880e 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -430,17 +430,17 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) h->workaround_bugs = avctx->workaround_bugs; h->flags = avctx->flags; h->poc.prev_poc_msb = 1 << 16; - h->x264_build = -1; h->recovery_frame = -1; h->frame_recovered = 0; h->poc.prev_frame_num = -1; - h->sei_fpa.frame_packing_arrangement_cancel_flag = -1; + h->sei.frame_packing.frame_packing_arrangement_cancel_flag = -1; + h->sei.unregistered.x264_build = -1; h->next_outputed_poc = INT_MIN; for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) h->last_pocs[i] = INT_MIN; - ff_h264_reset_sei(h); + ff_h264_sei_uninit(&h->sei); avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; @@ -594,7 +594,8 @@ static void decode_postinit(H264Context *h, int setup_finished) * decoding process if it exists. */ if (sps->pic_struct_present_flag) { - switch (h->sei_pic_struct) { + H264SEIPictureTiming *pt = &h->sei.picture_timing; + switch (pt->pic_struct) { case SEI_PIC_STRUCT_FRAME: break; case SEI_PIC_STRUCT_TOP_FIELD: @@ -624,9 +625,9 @@ static void decode_postinit(H264Context *h, int setup_finished) break; } - if ((h->sei_ct_type & 3) && - h->sei_pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP) - cur->f->interlaced_frame = (h->sei_ct_type & (1 << 1)) != 0; + if ((pt->ct_type & 3) && + pt->pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP) + cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0; } else { /* Derive interlacing flag from used decoding process. */ cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h); @@ -640,8 +641,8 @@ static void decode_postinit(H264Context *h, int setup_finished) if (sps->pic_struct_present_flag) { /* Use picture timing SEI information. Even if it is a * information of a past frame, better than nothing. */ - if (h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM || - h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP) + if (h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM || + h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP) cur->f->top_field_first = 1; else cur->f->top_field_first = 0; @@ -655,14 +656,14 @@ static void decode_postinit(H264Context *h, int setup_finished) } } - if (h->sei_frame_packing_present && - h->frame_packing_arrangement_type >= 0 && - h->frame_packing_arrangement_type <= 6 && - h->content_interpretation_type > 0 && - h->content_interpretation_type < 3) { + if (h->sei.frame_packing.present && + h->sei.frame_packing.frame_packing_arrangement_type <= 6 && + h->sei.frame_packing.content_interpretation_type > 0 && + h->sei.frame_packing.content_interpretation_type < 3) { + H264SEIFramePacking *fp = &h->sei.frame_packing; AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f); if (stereo) { - switch (h->frame_packing_arrangement_type) { + switch (fp->frame_packing_arrangement_type) { case 0: stereo->type = AV_STEREO3D_CHECKERBOARD; break; @@ -673,7 +674,7 @@ static void decode_postinit(H264Context *h, int setup_finished) stereo->type = AV_STEREO3D_LINES; break; case 3: - if (h->quincunx_subsampling) + if (fp->quincunx_sampling_flag) stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX; else stereo->type = AV_STEREO3D_SIDEBYSIDE; @@ -689,42 +690,46 @@ static void decode_postinit(H264Context *h, int setup_finished) break; } - if (h->content_interpretation_type == 2) + if (fp->content_interpretation_type == 2) stereo->flags = AV_STEREO3D_FLAG_INVERT; } } - if (h->sei_display_orientation_present && - (h->sei_anticlockwise_rotation || h->sei_hflip || h->sei_vflip)) { - double angle = h->sei_anticlockwise_rotation * 360 / (double) (1 << 16); + if (h->sei.display_orientation.present && + (h->sei.display_orientation.anticlockwise_rotation || + h->sei.display_orientation.hflip || + h->sei.display_orientation.vflip)) { + H264SEIDisplayOrientation *o = &h->sei.display_orientation; + double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16); AVFrameSideData *rotation = av_frame_new_side_data(cur->f, AV_FRAME_DATA_DISPLAYMATRIX, sizeof(int32_t) * 9); if (rotation) { av_display_rotation_set((int32_t *)rotation->data, angle); av_display_matrix_flip((int32_t *)rotation->data, - h->sei_hflip, h->sei_vflip); + o->hflip, o->vflip); } } - if (h->sei_reguserdata_afd_present) { + if (h->sei.afd.present) { AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD, sizeof(uint8_t)); if (sd) { - *sd->data = h->active_format_description; - h->sei_reguserdata_afd_present = 0; + *sd->data = h->sei.afd.active_format_description; + h->sei.afd.present = 0; } } - if (h->a53_caption) { + if (h->sei.a53_caption.a53_caption) { + H264SEIA53Caption *a53 = &h->sei.a53_caption; AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_A53_CC, - h->a53_caption_size); + a53->a53_caption_size); if (sd) - memcpy(sd->data, h->a53_caption, h->a53_caption_size); - av_freep(&h->a53_caption); - h->a53_caption_size = 0; + memcpy(sd->data, a53->a53_caption, a53->a53_caption_size); + av_freep(&a53->a53_caption); + a53->a53_caption_size = 0; h->avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS; } @@ -859,7 +864,7 @@ void ff_h264_flush_change(H264Context *h) ff_h264_unref_picture(h, &h->last_pic_for_ec); h->first_field = 0; - ff_h264_reset_sei(h); + ff_h264_sei_uninit(&h->sei); h->recovery_frame = -1; h->frame_recovered = 0; h->current_slice = 0; @@ -1005,7 +1010,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, h->current_slice = 0; if (!h->first_field) h->cur_pic_ptr = NULL; - ff_h264_reset_sei(h); + ff_h264_sei_uninit(&h->sei); } if (h->nal_length_size == 4) { @@ -1096,13 +1101,15 @@ again: if ((err = ff_h264_decode_slice_header(h, sl))) break; - if (h->sei_recovery_frame_cnt >= 0) { - if (h->poc.frame_num != h->sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I) + if (h->sei.recovery_point.recovery_frame_cnt >= 0) { + const int sei_recovery_frame_cnt = h->sei.recovery_point.recovery_frame_cnt; + + if (h->poc.frame_num != sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I) h->valid_recovery_point = 1; if ( h->recovery_frame < 0 - || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > h->sei_recovery_frame_cnt) { - h->recovery_frame = av_mod_uintp2(h->poc.frame_num + h->sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num); + || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > sei_recovery_frame_cnt) { + h->recovery_frame = av_mod_uintp2(h->poc.frame_num + sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num); if (!h->valid_recovery_point) h->recovery_frame = h->poc.frame_num; @@ -1167,10 +1174,15 @@ again: avpriv_request_sample(avctx, "data partitioning"); break; case NAL_SEI: - h->gb = nal->gb; - ret = ff_h264_decode_sei(h); + ret = ff_h264_sei_decode(&h->sei, &nal->gb, &h->ps, avctx); + h->has_recovery_point = h->has_recovery_point || h->sei.recovery_point.recovery_frame_cnt != -1; if (avctx->debug & FF_DEBUG_GREEN_MD) - debug_green_metadata(&h->sei_green_metadata, h->avctx); + debug_green_metadata(&h->sei.green_metadata, h->avctx); +#if FF_API_AFD +FF_DISABLE_DEPRECATION_WARNINGS + h->avctx->dtg_active_format = h->sei.afd.active_format_description; +FF_ENABLE_DEPRECATION_WARNINGS +#endif /* FF_API_AFD */ if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) goto end; break; @@ -1314,7 +1326,7 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) if (ret < 0) return ret; - av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(h), 0); + av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(&h->sei.frame_packing), 0); h->backup_width = h->avctx->width; h->backup_height = h->avctx->height; @@ -1532,8 +1544,7 @@ av_cold void ff_h264_free_context(H264Context *h) av_freep(&h->slice_ctx); h->nb_slice_ctx = 0; - h->a53_caption_size = 0; - av_freep(&h->a53_caption); + ff_h264_sei_uninit(&h->sei); for (i = 0; i < MAX_SPS_COUNT; i++) av_buffer_unref(&h->ps.sps_list[i]); |