Commit 1189af42 authored by Andreas Cadhalpun's avatar Andreas Cadhalpun

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: 's avatarMichael Niedermayer <michaelni@gmx.at>
Signed-off-by: 's avatarAndreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
parent b5c71fba
......@@ -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 */
......
......@@ -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;
......
......@@ -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]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment