Hi,

2014-08-21 3:06 GMT+02:00 Michael Niedermayer <michae...@gmx.at>:
> heres a narrower solution for this file
> not sure its better
> i can apply whichever you prefer, probably we wont find out which
> is the best solution before pushing something and waiting for more
> bug reports

Thanks for narrowing it done, and now I have dug it further.

When you look at what get parsed before that,
vui->def_disp_win.left_offset gets an insane value unrelated to the
video dimensions. I tried  instead to do as if
vui->default_display_window_flag and related syntax does not exist.

Then, the timing info is decoded, and the values are actually normal:
vui_num_units_in_tick = 1000
vui_time_scale = 23976
(rest less relevant and meaningfull)

So I think the actual "bug" in that stream is that it does not contain
any default_display_window information. Why is that? Probably because
the encoder writes an older VUI syntax, and several bits get
misinterpreted. By luck they don't bother us. It would be nice to know
what syntax is used, but there could be so many variations...

The attached therefore barely improves on your patch.

-- 
Christophe
From 80cd353f464f3785285e0c82efd3c6ccd655bf5c Mon Sep 17 00:00:00 2001
From: Christophe Gisquet <christophe.gisq...@gmail.com>
Date: Thu, 21 Aug 2014 18:57:18 +0200
Subject: [PATCH] hevc_ps: check overflow and test alternate syntax

Some streams were found to have what appeared to be truncated SPS.
Their syntax seem to be valid at least until the end of the VUI, so
try that syntax if the parsing would overflow the SPS in the
conforming syntax.

Fixes ticket #3872.
---
 libavcodec/hevc_ps.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 2ccce5f..29412d2 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);
-- 
1.9.2.msysgit.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to