From 078be09dd713142b0e6598d32b755883f8e36b71 Mon Sep 17 00:00:00 2001 From: Andreas Cadhalpun Date: Sat, 31 Jan 2015 20:36:07 +0100 Subject: examples/demuxing_decoding: abort decoding when width, height or pix_fmt change This is necessary, because avcodec_decode_video2 can change width, height and/or pixel format of the AVCodecContext. Since video_dst_data and video_dst_linesize are not updated by calling av_image_alloc again, av_image_copy[_plane] asserts, because the destination buffer is too small. In this case, creating a useable rawvideo is not possible anyway, since it has fixed width/height/pix_fmt. Signed-off-by: Andreas Cadhalpun Signed-off-by: Michael Niedermayer --- doc/examples/demuxing_decoding.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'doc/examples') diff --git a/doc/examples/demuxing_decoding.c b/doc/examples/demuxing_decoding.c index 30bee1dca5..feeeb967f8 100644 --- a/doc/examples/demuxing_decoding.c +++ b/doc/examples/demuxing_decoding.c @@ -36,6 +36,8 @@ static AVFormatContext *fmt_ctx = NULL; static AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx; +static int width, height; +static enum AVPixelFormat pix_fmt; static AVStream *video_stream = NULL, *audio_stream = NULL; static const char *src_filename = NULL; static const char *video_dst_filename = NULL; @@ -79,6 +81,20 @@ static int decode_packet(int *got_frame, int cached) fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret)); return ret; } + if (video_dec_ctx->width != width || video_dec_ctx->height != height || + video_dec_ctx->pix_fmt != pix_fmt) { + /* To handle this change, one could call av_image_alloc again and + * decode the following frames into another rawvideo file. */ + fprintf(stderr, "Error: Width, height and pixel format have to be " + "constant in a rawvideo file, but the width, height or " + "pixel format of the input video changed:\n" + "old: width = %d, height = %d, format = %s\n" + "new: width = %d, height = %d, format = %s\n", + width, height, av_get_pix_fmt_name(pix_fmt), + video_dec_ctx->width, video_dec_ctx->height, + av_get_pix_fmt_name(video_dec_ctx->pix_fmt)); + return -1; + } if (*got_frame) { printf("video_frame%s n:%d coded_n:%d pts:%s\n", @@ -90,7 +106,7 @@ static int decode_packet(int *got_frame, int cached) * this is required since rawvideo expects non aligned data */ av_image_copy(video_dst_data, video_dst_linesize, (const uint8_t **)(frame->data), frame->linesize, - video_dec_ctx->pix_fmt, video_dec_ctx->width, video_dec_ctx->height); + pix_fmt, width, height); /* write to rawvideo file */ fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file); @@ -265,9 +281,11 @@ int main (int argc, char **argv) } /* allocate image where the decoded image will be put */ + width = video_dec_ctx->width; + height = video_dec_ctx->height; + pix_fmt = video_dec_ctx->pix_fmt; ret = av_image_alloc(video_dst_data, video_dst_linesize, - video_dec_ctx->width, video_dec_ctx->height, - video_dec_ctx->pix_fmt, 1); + width, height, pix_fmt, 1); if (ret < 0) { fprintf(stderr, "Could not allocate raw video buffer\n"); goto end; @@ -342,7 +360,7 @@ int main (int argc, char **argv) if (video_stream) { printf("Play the output video file with the command:\n" "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n", - av_get_pix_fmt_name(video_dec_ctx->pix_fmt), video_dec_ctx->width, video_dec_ctx->height, + av_get_pix_fmt_name(pix_fmt), width, height, video_dst_filename); } -- cgit v1.2.3