diff options
author | Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com> | 2015-06-09 23:38:26 +0200 |
---|---|---|
committer | Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com> | 2015-06-12 21:22:00 +0200 |
commit | 1189af429211ac650aac730368a6cf5b23756605 (patch) | |
tree | 6e91ea70c031cb700402c5f6b82905eb36cf930c /libavcodec/h264.c | |
parent | b5c71fba594353b0676fa41c1f279d42adb6e716 (diff) | |
download | ffmpeg-1189af429211ac650aac730368a6cf5b23756605.tar.gz |
h264: update avctx width/height/pix_fmt when returning frame
Inconsistencies between the dimensions/pixel format of avctx and the
frame can confuse API users.
For example this can crash the demuxing_decoding example.
Back up the previous values and restore them, when decoding the next
frame. This is necessary, because these can be different between the
returned frame and the last decoded frame.
Reviewed-by: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 9a002142cc..9be317c55f 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -591,6 +591,9 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h) int i; h->avctx = avctx; + h->backup_width = -1; + h->backup_height = -1; + h->backup_pix_fmt = AV_PIX_FMT_NONE; h->dequant_coeff_pps = -1; h->current_sps_id = -1; h->cur_chroma_format_idc = -1; @@ -1675,6 +1678,14 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) av_dict_set(&dst->metadata, "stereo_mode", ff_h264_sei_stereo_mode(h), 0); + h->backup_width = h->avctx->width; + h->backup_height = h->avctx->height; + h->backup_pix_fmt = h->avctx->pix_fmt; + + h->avctx->width = dst->width; + h->avctx->height = dst->height; + h->avctx->pix_fmt = dst->format; + if (srcp->sei_recovery_frame_cnt == 0) dst->key_frame = 1; if (!srcp->crop) @@ -1726,6 +1737,19 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, h->flags = avctx->flags; + if (h->backup_width != -1) { + avctx->width = h->backup_width; + h->backup_width = -1; + } + if (h->backup_height != -1) { + avctx->height = h->backup_height; + h->backup_height = -1; + } + if (h->backup_pix_fmt != AV_PIX_FMT_NONE) { + avctx->pix_fmt = h->backup_pix_fmt; + h->backup_pix_fmt = AV_PIX_FMT_NONE; + } + ff_h264_unref_picture(h, &h->last_pic_for_ec); /* end of stream, output what is still in the buffers */ |