| @@ -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) { | |||