diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 9a002142ccf4942cfd8c9f76761fda9a82749d27..9be317c55fda7bc50cccc8993c5d0862fec5d721 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 */ diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 95db912465b893dfa2299f0861a357308147c56f..548510d793016ea8939cbd058a54345cc4877c60 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -519,6 +519,14 @@ typedef struct H264Context { int width, height; int chroma_x_shift, chroma_y_shift; + /** + * Backup frame properties: needed, because they can be different + * between returned frame and last decoded frame. + **/ + int backup_width; + int backup_height; + enum AVPixelFormat backup_pix_fmt; + int droppable; int coded_picture_number; int low_delay; diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 9c4d613195c4b4e6c259e5dd98281b01750e8c7f..0c0812f472ad69ee467e8d0d16c552ee19de49f2 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -497,6 +497,9 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->picture_structure = h1->picture_structure; h->droppable = h1->droppable; h->low_delay = h1->low_delay; + h->backup_width = h1->backup_width; + h->backup_height = h1->backup_height; + h->backup_pix_fmt = h1->backup_pix_fmt; for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) { ff_h264_unref_picture(h, &h->DPB[i]);