diff options
author | Clément Bœsch <cboesch@gopro.com> | 2017-01-17 10:50:01 +0100 |
---|---|---|
committer | Clément Bœsch <u@pkh.me> | 2017-01-18 18:06:21 +0100 |
commit | c3050fcbdcb2dbaecab662836afd0d1b7badbf10 (patch) | |
tree | 8b18d4af14dd1faec1c09ac97b95e816393a1bae /libavcodec/h264dec.c | |
parent | 83a9cf3603ecac299aed603c3c9371de8d3cd90d (diff) |
lavc/h264dec: remove flush goto in decode callback
Diffstat (limited to 'libavcodec/h264dec.c')
-rw-r--r-- | libavcodec/h264dec.c | 70 |
1 files changed, 37 insertions, 33 deletions
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 821ae14434..c24818bde4 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -966,6 +966,39 @@ static int finalize_frame(H264Context *h, AVFrame *dst, H264Picture *out, int *g return 0; } +static int send_next_delayed_frame(H264Context *h, AVFrame *dst_frame, + int *got_frame, int buf_index) +{ + int ret, i, out_idx; + H264Picture *out = h->delayed_pic[0]; + + h->cur_pic_ptr = NULL; + h->first_field = 0; + + out_idx = 0; + for (i = 1; + h->delayed_pic[i] && + !h->delayed_pic[i]->f->key_frame && + !h->delayed_pic[i]->mmco_reset; + i++) + if (h->delayed_pic[i]->poc < out->poc) { + out = h->delayed_pic[i]; + out_idx = i; + } + + for (i = out_idx; h->delayed_pic[i]; i++) + h->delayed_pic[i] = h->delayed_pic[i + 1]; + + if (out) { + out->reference &= ~DELAYED_PIC_REF; + ret = finalize_frame(h, dst_frame, out, got_frame); + if (ret < 0) + return ret; + } + + return buf_index; +} + static int h264_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -973,9 +1006,7 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; H264Context *h = avctx->priv_data; AVFrame *pict = data; - int buf_index = 0; - H264Picture *out; - int i, out_idx; + int buf_index; int ret; h->flags = avctx->flags; @@ -997,36 +1028,9 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, ff_h264_unref_picture(h, &h->last_pic_for_ec); /* end of stream, output what is still in the buffers */ - if (buf_size == 0) { - out: - - h->cur_pic_ptr = NULL; - h->first_field = 0; - - out = h->delayed_pic[0]; - out_idx = 0; - for (i = 1; - h->delayed_pic[i] && - !h->delayed_pic[i]->f->key_frame && - !h->delayed_pic[i]->mmco_reset; - i++) - if (h->delayed_pic[i]->poc < out->poc) { - out = h->delayed_pic[i]; - out_idx = i; - } - - for (i = out_idx; h->delayed_pic[i]; i++) - h->delayed_pic[i] = h->delayed_pic[i + 1]; + if (buf_size == 0) + return send_next_delayed_frame(h, pict, got_frame, 0); - if (out) { - out->reference &= ~DELAYED_PIC_REF; - ret = finalize_frame(h, pict, out, got_frame); - if (ret < 0) - return ret; - } - - return buf_index; - } if (h->is_avc && av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) { int side_size; uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); @@ -1048,7 +1052,7 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, if (!h->cur_pic_ptr && h->nal_unit_type == H264_NAL_END_SEQUENCE) { av_assert0(buf_index <= buf_size); - goto out; + return send_next_delayed_frame(h, pict, got_frame, buf_index); } if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) { |