On Wed, Nov 30, 2011 at 1:22 AM, Ronald S. Bultje <rsbul...@gmail.com> wrote:
> Fixes fate-h264-conformance-{mr2_tandberg_e,mr3_tandberg_b} without
> requiring -strict 1.
> ---
>  libavcodec/h264.c      |   69 +++++++++++++++++++++++++++++++++++------------
>  libavcodec/h264.h      |    1 +
>  libavcodec/h264_refs.c |    6 +---
>  3 files changed, 53 insertions(+), 23 deletions(-)
>
> diff --git a/libavcodec/h264.c b/libavcodec/h264.c
> index ad1ab69..acd7179 100644
> --- a/libavcodec/h264.c
> +++ b/libavcodec/h264.c
> @@ -1348,6 +1348,7 @@ static void decode_postinit(H264Context *h, int 
> setup_finished){
>     Picture *out = s->current_picture_ptr;
>     Picture *cur = s->current_picture_ptr;
>     int i, pics, out_of_order, out_idx;
> +    int invalid = 0, cnt = 0;
>
>     s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
>     s->current_picture_ptr->f.pict_type   = s->pict_type;
> @@ -1438,7 +1439,7 @@ static void decode_postinit(H264Context *h, int 
> setup_finished){
>
>     if(   s->avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT
>        && !h->sps.bitstream_restriction_flag){
> -        s->avctx->has_b_frames= MAX_DELAYED_PIC_COUNT;
> +        s->avctx->has_b_frames = MAX_DELAYED_PIC_COUNT - 1;
>         s->low_delay= 0;
>     }
>

This part looks OK.

> @@ -1451,31 +1452,54 @@ 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.
> +     * FIXME: 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 we will fix later. */
> +    for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) {
> +        cnt     += out->poc < h->last_pocs[i];
> +        invalid += out->poc == INT_MIN;
> +    }
> +    if (!h->mmco_reset && !cur->f.key_frame && cnt + invalid == 
> MAX_DELAYED_PIC_COUNT && cnt > 0) {
> +        h->mmco_reset = 2;

You set mmco_reset to 1 and 2 but I only see comparisons of it against 0.

What samples does this fix?

> +        if (pics > 1)
> +            h->delayed_pic[pics - 2]->mmco_reset = 2;
> +    }
> +    if (h->mmco_reset || cur->f.key_frame) {
> +        for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
> +            h->last_pocs[i] = INT_MIN;
> +        cnt     = 0;
> +        invalid = MAX_DELAYED_PIC_COUNT;
> +    }
>     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)
>         { }
>     else if (out_of_order && pics-1 == s->avctx->has_b_frames &&
>              s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {
> -        int cnt = 0, invalid = 0;
> -        for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) {
> -            cnt += out->poc < h->last_pocs[i];
> -            invalid += h->last_pocs[i] == INT_MIN;
> -        }
>         if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {
>             s->avctx->has_b_frames = FFMAX(s->avctx->has_b_frames, cnt);
> -        } else if (cnt) {
> -            for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
> -                h->last_pocs[i] = INT_MIN;
>         }
>         s->low_delay = 0;
>     } else if (s->low_delay &&
> @@ -1485,7 +1509,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
> @@ -1493,13 +1517,20 @@ static void decode_postinit(H264Context *h, int 
> setup_finished){
>             h->delayed_pic[i] = h->delayed_pic[i+1];
>     }
>     memmove(h->last_pocs, &h->last_pocs[1], sizeof(*h->last_pocs) * 
> (MAX_DELAYED_PIC_COUNT - 1));
> -    h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = out->poc;
> +    h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = cur->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)) {
> -            h->next_outputed_poc = INT_MIN;
> -        } else
> +        if (out->mmco_reset) {
> +            if (out_idx > 0) {
> +                h->next_outputed_poc = out->poc;
> +                h->delayed_pic[out_idx - 1]->mmco_reset = out->mmco_reset;
> +            } else {
> +                h->next_outputed_poc = INT_MIN;
> +            }
> +        } else {
>             h->next_outputed_poc = out->poc;
> +        }
> +        h->mmco_reset = 0;
>     }else{
>         av_log(s->avctx, AV_LOG_DEBUG, "no picture\n");
>     }
> @@ -2353,6 +2384,8 @@ static void flush_dpb(AVCodecContext *avctx){
>             h->delayed_pic[i]->f.reference = 0;
>         h->delayed_pic[i]= NULL;
>     }
> +    for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
> +        h->last_pocs[i] = INT_MIN;
>     h->outputed_poc=h->next_outputed_poc= INT_MIN;
>     h->prev_interlaced_frame = 1;
>     idr(h);
> 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
> libav-devel@libav.org
> https://lists.libav.org/mailman/listinfo/libav-devel
>
_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to