Ronald S. Bultje <[email protected]> added the comment:

The attached patch fixes the crash for me. The problem is that on 
resolution change, the decoded NALs are free'ed in free_tables() and 
then reused directly after that (after reinit) during decoding of the 
actual data, this of course crashes. The attached patch fixes that.

There's still some corrupt data at the bottom of the images, is that 
also a bug or was that always there?

________________________________________________
FFmpeg issue tracker <[email protected]>
<https://roundup.ffmpeg.org/issue2393>
________________________________________________
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 40dc276..2dc8045 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -614,7 +614,7 @@ static void hl_motion(H264Context *h, uint8_t *dest_y, 
uint8_t *dest_cb, uint8_t
 }
 
 
-static void free_tables(H264Context *h){
+static void free_tables(H264Context *h, int free_rbsp){
     int i;
     H264Context *hx;
     av_freep(&h->intra4x4_pred_mode);
@@ -637,10 +637,12 @@ static void free_tables(H264Context *h){
         av_freep(&hx->top_borders[1]);
         av_freep(&hx->top_borders[0]);
         av_freep(&hx->s.obmc_scratchpad);
+        if (free_rbsp){
         av_freep(&hx->rbsp_buffer[1]);
         av_freep(&hx->rbsp_buffer[0]);
         hx->rbsp_buffer_size[0] = 0;
         hx->rbsp_buffer_size[1] = 0;
+        }
         if (i) av_freep(&h->thread_context[i]);
     }
 }
@@ -748,7 +750,7 @@ int ff_h264_alloc_tables(H264Context *h){
 
     return 0;
 fail:
-    free_tables(h);
+    free_tables(h, 1);
     return -1;
 }
 
@@ -1776,7 +1778,7 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0){
             || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) {
         if(h != h0)
             return -1;   // width / height changed during parallelized decoding
-        free_tables(h);
+        free_tables(h, 0);
         flush_dpb(s->avctx);
         MPV_common_end(s);
     }
@@ -1784,6 +1786,7 @@ static int decode_slice_header(H264Context *h, 
H264Context *h0){
         if(h != h0)
             return -1;  // we cant (re-)initialize context during parallel 
decoding
 
+printf("Reinit\n");
         avcodec_set_dimensions(s->avctx, s->width, s->height);
         s->avctx->sample_aspect_ratio= h->sps.sar;
         av_assert0(s->avctx->sample_aspect_ratio.den);
@@ -3331,7 +3334,7 @@ av_cold void ff_h264_free_context(H264Context *h)
 {
     int i;
 
-    free_tables(h); //FIXME cleanup init stuff perhaps
+    free_tables(h, 1); //FIXME cleanup init stuff perhaps
 
     for(i = 0; i < MAX_SPS_COUNT; i++)
         av_freep(h->sps_buffers + i);

Reply via email to