[FFmpeg-cvslog] examples/demuxing_decoding: abort decoding when width, height or pix_fmt change
Andreas Cadhalpun
git at videolan.org
Tue Feb 10 03:34:21 CET 2015
ffmpeg | branch: master | Andreas Cadhalpun <Andreas.Cadhalpun at googlemail.com> | Sat Jan 31 20:36:07 2015 +0100| [078be09dd713142b0e6598d32b755883f8e36b71] | committer: Michael Niedermayer
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 <Andreas.Cadhalpun at googlemail.com>
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=078be09dd713142b0e6598d32b755883f8e36b71
---
doc/examples/demuxing_decoding.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/doc/examples/demuxing_decoding.c b/doc/examples/demuxing_decoding.c
index 30bee1d..feeeb96 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);
}
More information about the ffmpeg-cvslog
mailing list