|
|
|
@ -1037,6 +1037,59 @@ static int is_extra(const uint8_t *buf, int buf_size) |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int finalize_frame(H264Context *h, AVFrame *dst, H264Picture *out, int *got_frame) |
|
|
|
|
{ |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
if (((h->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) || |
|
|
|
|
(h->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL) || |
|
|
|
|
out->recovered)) { |
|
|
|
|
|
|
|
|
|
if (!out->recovered) |
|
|
|
|
out->f->flags |= AV_FRAME_FLAG_CORRUPT; |
|
|
|
|
|
|
|
|
|
if (!h->avctx->hwaccel && |
|
|
|
|
(out->field_poc[0] == INT_MAX || |
|
|
|
|
out->field_poc[1] == INT_MAX) |
|
|
|
|
) { |
|
|
|
|
int p; |
|
|
|
|
AVFrame *f = out->f; |
|
|
|
|
int field = out->field_poc[0] == INT_MAX; |
|
|
|
|
uint8_t *dst_data[4]; |
|
|
|
|
int linesizes[4]; |
|
|
|
|
const uint8_t *src_data[4]; |
|
|
|
|
|
|
|
|
|
av_log(h->avctx, AV_LOG_DEBUG, "Duplicating field %d to fill missing\n", field); |
|
|
|
|
|
|
|
|
|
for (p = 0; p<4; p++) { |
|
|
|
|
dst_data[p] = f->data[p] + (field^1)*f->linesize[p]; |
|
|
|
|
src_data[p] = f->data[p] + field *f->linesize[p]; |
|
|
|
|
linesizes[p] = 2*f->linesize[p]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
av_image_copy(dst_data, linesizes, src_data, linesizes, |
|
|
|
|
f->format, f->width, f->height>>1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = output_frame(h, dst, out); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
*got_frame = 1; |
|
|
|
|
|
|
|
|
|
if (CONFIG_MPEGVIDEO) { |
|
|
|
|
ff_print_debug_info2(h->avctx, dst, NULL, |
|
|
|
|
out->mb_type, |
|
|
|
|
out->qscale_table, |
|
|
|
|
out->motion_val, |
|
|
|
|
NULL, |
|
|
|
|
h->mb_width, h->mb_height, h->mb_stride, 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int h264_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
int *got_frame, AVPacket *avpkt) |
|
|
|
|
{ |
|
|
|
@ -1074,7 +1127,6 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
h->cur_pic_ptr = NULL; |
|
|
|
|
h->first_field = 0; |
|
|
|
|
|
|
|
|
|
// FIXME factorize this with the output code below
|
|
|
|
|
out = h->delayed_pic[0]; |
|
|
|
|
out_idx = 0; |
|
|
|
|
for (i = 1; |
|
|
|
@ -1092,10 +1144,9 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
|
|
|
|
|
if (out) { |
|
|
|
|
out->reference &= ~DELAYED_PIC_REF; |
|
|
|
|
ret = output_frame(h, pict, out); |
|
|
|
|
ret = finalize_frame(h, pict, out, got_frame); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
*got_frame = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return buf_index; |
|
|
|
@ -1141,48 +1192,10 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
/* Wait for second field. */ |
|
|
|
|
*got_frame = 0; |
|
|
|
|
if (h->next_output_pic && ((avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) || |
|
|
|
|
(avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL) || |
|
|
|
|
h->next_output_pic->recovered)) { |
|
|
|
|
if (!h->next_output_pic->recovered) |
|
|
|
|
h->next_output_pic->f->flags |= AV_FRAME_FLAG_CORRUPT; |
|
|
|
|
|
|
|
|
|
if (!h->avctx->hwaccel && |
|
|
|
|
(h->next_output_pic->field_poc[0] == INT_MAX || |
|
|
|
|
h->next_output_pic->field_poc[1] == INT_MAX) |
|
|
|
|
) { |
|
|
|
|
int p; |
|
|
|
|
AVFrame *f = h->next_output_pic->f; |
|
|
|
|
int field = h->next_output_pic->field_poc[0] == INT_MAX; |
|
|
|
|
uint8_t *dst_data[4]; |
|
|
|
|
int linesizes[4]; |
|
|
|
|
const uint8_t *src_data[4]; |
|
|
|
|
|
|
|
|
|
av_log(h->avctx, AV_LOG_DEBUG, "Duplicating field %d to fill missing\n", field); |
|
|
|
|
|
|
|
|
|
for (p = 0; p<4; p++) { |
|
|
|
|
dst_data[p] = f->data[p] + (field^1)*f->linesize[p]; |
|
|
|
|
src_data[p] = f->data[p] + field *f->linesize[p]; |
|
|
|
|
linesizes[p] = 2*f->linesize[p]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
av_image_copy(dst_data, linesizes, src_data, linesizes, |
|
|
|
|
f->format, f->width, f->height>>1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ret = output_frame(h, pict, h->next_output_pic); |
|
|
|
|
if (h->next_output_pic) { |
|
|
|
|
ret = finalize_frame(h, pict, h->next_output_pic, got_frame); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
*got_frame = 1; |
|
|
|
|
if (CONFIG_MPEGVIDEO) { |
|
|
|
|
ff_print_debug_info2(h->avctx, pict, NULL, |
|
|
|
|
h->next_output_pic->mb_type, |
|
|
|
|
h->next_output_pic->qscale_table, |
|
|
|
|
h->next_output_pic->motion_val, |
|
|
|
|
NULL, |
|
|
|
|
h->mb_width, h->mb_height, h->mb_stride, 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|