Fix #29202: Crash - VSE Cross strip probably leads to this

Crash was caused by several conditions:
- Frame which failed to decode tried to be converted to RGB colorspace
  and some filters like deinterlacing used to be applied as well
  (it's avscale stuff sws_scale where crash happened).
- In some cases it happened reading of freed memory when calling
  sws_scale function. Looks like it happened because of freeing
  packet on which decoding of frame finished and reading next packet.

Solved this two issues by making YUV->RGB conversion as soon as
frame was decoded in ffmpeg_decode_video_frame (such postprocessing
used to happen in callee of this function ffmpeg_fetchibuf), so now
sws_scale would be called before freeing packet on which decoding of
frame finished and it wouldn't be called in cases when decoding of
frame failed.

If decoding of frame failed, it'll be black ibuf returned to the sequencer.
This commit is contained in:
Sergey Sharybin 2011-11-15 07:00:01 +00:00
parent e8906f5254
commit 8a0da0b59e

@ -747,6 +747,8 @@ static int ffmpeg_decode_video_frame(struct anim * anim)
anim->next_pts =
av_get_pts_from_frame(anim->pFormatCtx,
anim->pFrame);
ffmpeg_postprocess(anim);
}
av_free_packet(&anim->next_packet);
@ -797,6 +799,8 @@ static int ffmpeg_decode_video_frame(struct anim * anim)
== AV_NOPTS_VALUE) ?
-1 : (long long int)anim->pFrame->pkt_pts,
(long long int)anim->next_pts);
ffmpeg_postprocess(anim);
}
}
av_free_packet(&anim->next_packet);
@ -808,6 +812,7 @@ static int ffmpeg_decode_video_frame(struct anim * anim)
AV_LOG_ERROR, " DECODE READ FAILED: av_read_frame() "
"returned error: %d\n", rval);
}
return (rval >= 0);
}
@ -947,6 +952,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position,
}
IMB_freeImBuf(anim->last_frame);
anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
if (anim->next_pts <= pts_to_search &&
anim->next_undecoded_pts > pts_to_search) {
@ -1050,10 +1056,6 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position,
ffmpeg_decode_video_frame(anim);
}
anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
ffmpeg_postprocess(anim);
anim->last_pts = anim->next_pts;
ffmpeg_decode_video_frame(anim);