Commit fbaf75b1 authored by Michael Niedermayer's avatar Michael Niedermayer

h264: Use the correct croping values.

This fixes returning pictures with corrupted data pointers.

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 5299ee54
...@@ -275,6 +275,9 @@ static int ref_picture(H264Context *h, Picture *dst, Picture *src) ...@@ -275,6 +275,9 @@ static int ref_picture(H264Context *h, Picture *dst, Picture *src)
dst->needs_realloc = src->needs_realloc; dst->needs_realloc = src->needs_realloc;
dst->reference = src->reference; dst->reference = src->reference;
dst->sync = src->sync; dst->sync = src->sync;
dst->crop = src->crop;
dst->crop_left = src->crop_left;
dst->crop_top = src->crop_top;
return 0; return 0;
fail: fail:
...@@ -349,6 +352,9 @@ static int alloc_picture(H264Context *h, Picture *pic) ...@@ -349,6 +352,9 @@ static int alloc_picture(H264Context *h, Picture *pic)
h->linesize = pic->f.linesize[0]; h->linesize = pic->f.linesize[0];
h->uvlinesize = pic->f.linesize[1]; h->uvlinesize = pic->f.linesize[1];
pic->crop = h->sps.crop;
pic->crop_top = h->sps.crop_top;
pic->crop_left= h->sps.crop_left;
if (h->avctx->hwaccel) { if (h->avctx->hwaccel) {
const AVHWAccel *hwaccel = h->avctx->hwaccel; const AVHWAccel *hwaccel = h->avctx->hwaccel;
...@@ -4843,21 +4849,22 @@ static int get_consumed_bytes(int pos, int buf_size) ...@@ -4843,21 +4849,22 @@ static int get_consumed_bytes(int pos, int buf_size)
return pos; return pos;
} }
static int output_frame(H264Context *h, AVFrame *dst, AVFrame *src) static int output_frame(H264Context *h, AVFrame *dst, Picture *srcp)
{ {
AVFrame *src = &srcp->f;
int i; int i;
int ret = av_frame_ref(dst, src); int ret = av_frame_ref(dst, src);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (!h->sps.crop) if (!srcp->crop)
return 0; return 0;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
int hshift = (i > 0) ? h->chroma_x_shift : 0; int hshift = (i > 0) ? h->chroma_x_shift : 0;
int vshift = (i > 0) ? h->chroma_y_shift : 0; int vshift = (i > 0) ? h->chroma_y_shift : 0;
int off = ((h->sps.crop_left >> hshift) << h->pixel_shift) + int off = ((srcp->crop_left >> hshift) << h->pixel_shift) +
(h->sps.crop_top >> vshift) * dst->linesize[i]; (srcp->crop_top >> vshift) * dst->linesize[i];
dst->data[i] += off; dst->data[i] += off;
} }
return 0; return 0;
...@@ -4902,7 +4909,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, ...@@ -4902,7 +4909,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
if (out) { if (out) {
out->reference &= ~DELAYED_PIC_REF; out->reference &= ~DELAYED_PIC_REF;
ret = output_frame(h, pict, &out->f); ret = output_frame(h, pict, out);
if (ret < 0) if (ret < 0)
return ret; return ret;
*got_frame = 1; *got_frame = 1;
...@@ -4960,7 +4967,7 @@ not_extra: ...@@ -4960,7 +4967,7 @@ not_extra:
/* Wait for second field. */ /* Wait for second field. */
*got_frame = 0; *got_frame = 0;
if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) { if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
ret = output_frame(h, pict, &h->next_output_pic->f); ret = output_frame(h, pict, h->next_output_pic);
if (ret < 0) if (ret < 0)
return ret; return ret;
*got_frame = 1; *got_frame = 1;
......
...@@ -177,6 +177,10 @@ typedef struct Picture{ ...@@ -177,6 +177,10 @@ typedef struct Picture{
int reference; int reference;
int shared; int shared;
int crop;
int crop_left;
int crop_top;
} Picture; } Picture;
/** /**
......
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