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);