---
libavcodec/h264.c | 38 +++++++++++++++++++++++++++++++-------
libavcodec/h264.h | 1 +
libavcodec/h264_refs.c | 6 +-----
3 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index ad1ab69..dcb712f 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1451,16 +1451,36 @@ static void decode_postinit(H264Context *h, int
setup_finished){
if (cur->f.reference == 0)
cur->f.reference = DELAYED_PIC_REF;
+ /* Frame reordering. This code takes pictures from coding order and sorts
+ * them by their incremental POC value into display order. It supports POC
+ * gaps, MMCO reset codes and random resets.
+ * A "display group" can start either with a IDR frame (f.key_frame = 1),
+ * and/or can be closed down with a MMCO reset code. In sequences where
+ * there is no delay, we can't detect that (since the frame was already
+ * output to the user), so we also set h->mmco_reset to detect the MMCO
+ * reset code.
+ * If we detect insufficient delays (as per s->avctx->has_b_frames), we
+ * increase the delay between input and output. All frames affected by
+ * the lag (e.g. those that should have been output before another frame
+ * that we already returned to the user) will be dropped. This is a bug
+ * that I will fix later (Ronald). */
+ if (h->mmco_reset || cur->f.key_frame) {
+ for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
+ h->last_pocs[i] = INT_MIN;
+ }
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++)
+ for (i = 1; i < MAX_DELAYED_PIC_COUNT && h->delayed_pic[i] &&
+ !h->delayed_pic[i-1]->mmco_reset && !h->delayed_pic[i]->f.key_frame;
i++)
+ {
if(h->delayed_pic[i]->poc < out->poc){
out = h->delayed_pic[i];
out_idx = i;
}
- if (s->avctx->has_b_frames == 0 && (h->delayed_pic[0]->f.key_frame ||
h->delayed_pic[0]->mmco_reset))
- h->next_outputed_poc= INT_MIN;
- out_of_order = out->poc < h->next_outputed_poc;
+ }
+ if (s->avctx->has_b_frames == 0 && (h->delayed_pic[0]->f.key_frame ||
h->mmco_reset))
+ h->next_outputed_poc = INT_MIN;
+ out_of_order = !out->f.key_frame && !h->mmco_reset && (out->poc <
h->next_outputed_poc);
if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames >=
h->sps.num_reorder_frames)
{ }
@@ -1474,8 +1494,10 @@ static void decode_postinit(H264Context *h, int
setup_finished){
if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {
s->avctx->has_b_frames = FFMAX(s->avctx->has_b_frames, cnt);
} else if (cnt) {
+ av_log(s->avctx, AV_LOG_WARNING, "Weird manual poc reset\n");
for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
h->last_pocs[i] = INT_MIN;
+ out_of_order = 0;
}
s->low_delay = 0;
} else if (s->low_delay &&
@@ -1485,7 +1507,7 @@ static void decode_postinit(H264Context *h, int
setup_finished){
s->avctx->has_b_frames++;
}
- if(out_of_order || pics > s->avctx->has_b_frames){
+ if(pics > s->avctx->has_b_frames){
out->f.reference &= ~DELAYED_PIC_REF;
out->owner2 = s; // for frame threading, the owner must be the second
field's thread
// or else the first thread can release the picture
and reuse it unsafely
@@ -1496,10 +1518,12 @@ static void decode_postinit(H264Context *h, int
setup_finished){
h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = out->poc;
if(!out_of_order && pics > s->avctx->has_b_frames){
h->next_output_pic = out;
- if (out_idx == 0 && h->delayed_pic[0] &&
(h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset)) {
+ if (out->mmco_reset || (h->mmco_reset && !h->delayed_pic[0])) {
h->next_outputed_poc = INT_MIN;
- } else
+ } else {
h->next_outputed_poc = out->poc;
+ }
+ h->mmco_reset = 0;
}else{
av_log(s->avctx, AV_LOG_DEBUG, "no picture\n");
}
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index caea7ba..5280e51 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -498,6 +498,7 @@ typedef struct H264Context{
*/
MMCO mmco[MAX_MMCO_COUNT];
int mmco_index;
+ int mmco_reset;
int long_ref_count; ///< number of actual long term references
int short_ref_count; ///< number of actual short term references
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 370b5c3..273c52b 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -582,13 +582,9 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO
*mmco, int mmco_count){
for(j = 0; j < 16; j++) {
remove_long(h, j, 0);
}
- s->current_picture_ptr->poc=
- s->current_picture_ptr->field_poc[0]=
- s->current_picture_ptr->field_poc[1]=
- h->poc_lsb=
- h->poc_msb=
h->frame_num=
s->current_picture_ptr->frame_num= 0;
+ h->mmco_reset = 1;
s->current_picture_ptr->mmco_reset=1;
break;
default: assert(0);
--
1.7.2.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel