diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/imbuf/intern/anim_movie.c | 54 |
1 files changed, 27 insertions, 27 deletions
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index c11c6d778a1..87f2fd124c0 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -939,14 +939,36 @@ static void ffmpeg_postprocess(struct anim *anim) } } -/* decode one video frame also considering the packet read into cur_packet */ +static void ffmpeg_decode_store_frame_pts(struct anim *anim) +{ + anim->cur_pts = av_get_pts_from_frame(anim->pFrame); + + if (anim->pFrame->key_frame) { + anim->cur_key_frame_pts = anim->cur_pts; + } + + av_log(anim->pFormatCtx, + AV_LOG_DEBUG, + " FRAME DONE: cur_pts=%" PRId64 ", guessed_pts=%" PRId64 "\n", + (anim->pFrame->pts == AV_NOPTS_VALUE) ? -1 : (int64_t)anim->pFrame->pts, + (int64_t)anim->cur_pts); +} +/* decode one video frame also considering the packet read into cur_packet */ static int ffmpeg_decode_video_frame(struct anim *anim) { - int rval = 0; - av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE VIDEO FRAME\n"); + /* Sometimes, decoder returns more than one frame per sent packet. Check if frames are available. + * This frames must be read, otherwise decoding will fail. See T91405. */ + anim->pFrameComplete = avcodec_receive_frame(anim->pCodecCtx, anim->pFrame) == 0; + if (anim->pFrameComplete) { + av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE FROM CODEC BUFFER\n"); + ffmpeg_decode_store_frame_pts(anim); + return 1; + } + + int rval = 0; if (anim->cur_packet->stream_index == anim->videoStream) { av_packet_unref(anim->cur_packet); anim->cur_packet->stream_index = -1; @@ -963,22 +985,11 @@ static int ffmpeg_decode_video_frame(struct anim *anim) (anim->cur_packet->pts == AV_NOPTS_VALUE) ? -1 : (int64_t)anim->cur_packet->pts, (anim->cur_packet->flags & AV_PKT_FLAG_KEY) ? " KEY" : ""); if (anim->cur_packet->stream_index == anim->videoStream) { - anim->pFrameComplete = 0; - avcodec_send_packet(anim->pCodecCtx, anim->cur_packet); anim->pFrameComplete = avcodec_receive_frame(anim->pCodecCtx, anim->pFrame) == 0; if (anim->pFrameComplete) { - anim->cur_pts = av_get_pts_from_frame(anim->pFrame); - - if (anim->pFrame->key_frame) { - anim->cur_key_frame_pts = anim->cur_pts; - } - av_log(anim->pFormatCtx, - AV_LOG_DEBUG, - " FRAME DONE: cur_pts=%" PRId64 ", guessed_pts=%" PRId64 "\n", - (anim->pFrame->pts == AV_NOPTS_VALUE) ? -1 : (int64_t)anim->pFrame->pts, - (int64_t)anim->cur_pts); + ffmpeg_decode_store_frame_pts(anim); break; } } @@ -988,22 +999,11 @@ static int ffmpeg_decode_video_frame(struct anim *anim) if (rval == AVERROR_EOF) { /* Flush any remaining frames out of the decoder. */ - anim->pFrameComplete = 0; - avcodec_send_packet(anim->pCodecCtx, NULL); anim->pFrameComplete = avcodec_receive_frame(anim->pCodecCtx, anim->pFrame) == 0; if (anim->pFrameComplete) { - anim->cur_pts = av_get_pts_from_frame(anim->pFrame); - - if (anim->pFrame->key_frame) { - anim->cur_key_frame_pts = anim->cur_pts; - } - av_log(anim->pFormatCtx, - AV_LOG_DEBUG, - " FRAME DONE (after EOF): cur_pts=%" PRId64 ", guessed_pts=%" PRId64 "\n", - (anim->pFrame->pts == AV_NOPTS_VALUE) ? -1 : (int64_t)anim->pFrame->pts, - (int64_t)anim->cur_pts); + ffmpeg_decode_store_frame_pts(anim); rval = 0; } } |