summaryrefslogtreecommitdiff
path: root/libavcodec/h264dec.c
diff options
context:
space:
mode:
authorClément Bœsch <cboesch@gopro.com>2017-01-13 11:18:10 +0100
committerClément Bœsch <cboesch@gopro.com>2017-01-16 10:43:41 +0100
commit9561de418378aeee0945e6535efdb9f8026116fa (patch)
tree0dc6f12aec8d7eb020aeeb6e4011c379a4c44737 /libavcodec/h264dec.c
parentbd520e85690183f73bdcd298100b22d58d6b205d (diff)
lavc/h264dec: reconstruct and debug flush frames as well
Diffstat (limited to 'libavcodec/h264dec.c')
-rw-r--r--libavcodec/h264dec.c99
1 files changed, 56 insertions, 43 deletions
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index ed0b7246b7..0cb0352485 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -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);
- }
}
}