diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 2ccce5f78c..29412d27ec 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -471,7 +471,8 @@ static void decode_vui(HEVCContext *s, HEVCSPS *sps) { VUI *vui = &sps->vui; GetBitContext *gb = &s->HEVClc->gb; - int sar_present; + GetBitContext backup; + int sar_present, alt = 1; av_log(s->avctx, AV_LOG_DEBUG, "Decoding VUI\n"); @@ -525,6 +526,10 @@ static void decode_vui(HEVCContext *s, HEVCSPS *sps) vui->frame_field_info_present_flag = get_bits1(gb); vui->default_display_window_flag = get_bits1(gb); + // Backup context in case an alternate header is detected + if( get_bits_left(gb) >= 66) + memcpy(&backup, gb, sizeof(backup)); + if (vui->default_display_window_flag) { //TODO: * 2 is only valid for 420 vui->def_disp_win.left_offset = get_ue_golomb_long(gb) * 2; @@ -552,8 +557,22 @@ static void decode_vui(HEVCContext *s, HEVCSPS *sps) vui->vui_timing_info_present_flag = get_bits1(gb); if (vui->vui_timing_info_present_flag) { + if( get_bits_left(gb) < 66) { + // The alternate syntax seem to have timing info located + // at where def_disp_win is normally located + av_log(s->avctx, AV_LOG_WARNING, + "Strange VUI timing information, retrying...\n"); + vui->default_display_window_flag = 0; + memset(&vui->def_disp_win, 0, sizeof(vui->def_disp_win)); + memcpy(gb, &backup, sizeof(backup)); + alt = 1; + } vui->vui_num_units_in_tick = get_bits_long(gb, 32); vui->vui_time_scale = get_bits_long(gb, 32); + if (alt) { + av_log(s->avctx, AV_LOG_INFO, "Retry got %i/%i fps\n", + vui->vui_time_scale, vui->vui_num_units_in_tick); + } vui->vui_poc_proportional_to_timing_flag = get_bits1(gb); if (vui->vui_poc_proportional_to_timing_flag) vui->vui_num_ticks_poc_diff_one_minus1 = get_ue_golomb_long(gb);