On 2016-03-21 15:00:23 +0100, Anton Khirnov wrote:
> ---
>  libavcodec/Makefile |   3 +-
>  libavcodec/h264.c   | 443 
> ++++++++++++++++++----------------------------------
>  libavcodec/h264.h   |   3 +
>  3 files changed, 154 insertions(+), 295 deletions(-)
> 
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 9892f85..8592410 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -251,7 +251,8 @@ OBJS-$(CONFIG_H263_ENCODER)            += mpeg4videoenc.o 
> mpeg4video.o  \
>  OBJS-$(CONFIG_H264_DECODER)            += h264.o h264_cabac.o h264_cavlc.o \
>                                            h264_direct.o h264_loopfilter.o  \
>                                            h264_mb.o h264_picture.o h264_ps.o 
> \
> -                                          h264_refs.o h264_sei.o h264_slice.o
> +                                          h264_refs.o h264_sei.o 
> h264_slice.o \
> +                                          h2645_parse.o
>  OBJS-$(CONFIG_H264_MMAL_DECODER)       += mmaldec.o
>  OBJS-$(CONFIG_H264_NVENC_ENCODER)      += nvenc_h264.o
>  OBJS-$(CONFIG_H264_QSV_DECODER)        += qsvdec_h2645.o
> diff --git a/libavcodec/h264.c b/libavcodec/h264.c
> index 613c633..241258f 100644
> --- a/libavcodec/h264.c
> +++ b/libavcodec/h264.c
> @@ -38,6 +38,7 @@
>  #include "error_resilience.h"
>  #include "avcodec.h"
>  #include "h264.h"
> +#include "h2645_parse.h"
>  #include "h264data.h"
>  #include "h264chroma.h"
>  #include "h264_mvpred.h"
> @@ -315,25 +316,6 @@ nsc:
>      return dst;
>  }
>  
> -/**
> - * Identify the exact end of the bitstream
> - * @return the length of the trailing, or 0 if damaged
> - */
> -static int decode_rbsp_trailing(H264Context *h, const uint8_t *src)
> -{
> -    int v = *src;
> -    int r;
> -
> -    ff_tlog(h->avctx, "rbsp trailing %X\n", v);
> -
> -    for (r = 1; r < 9; r++) {
> -        if (v & 1)
> -            return r;
> -        v >>= 1;
> -    }
> -    return 0;
> -}
> -
>  void ff_h264_free_tables(H264Context *h)
>  {
>      int i;
> @@ -1284,113 +1266,30 @@ int ff_set_ref_count(H264Context *h, 
> H264SliceContext *sl)
>      return 0;
>  }
>  
> -static int find_start_code(const uint8_t *buf, int buf_size,
> -                           int buf_index, int next_avc)
> -{
> -    // start code prefix search
> -    for (; buf_index + 3 < next_avc; buf_index++)
> -        // This should always succeed in the first iteration.
> -        if (buf[buf_index]     == 0 &&
> -            buf[buf_index + 1] == 0 &&
> -            buf[buf_index + 2] == 1)
> -            break;
> -
> -    if (buf_index + 3 >= buf_size)
> -        return buf_size;
> -
> -    return buf_index + 3;
> -}
> -
> -static int get_avc_nalsize(H264Context *h, const uint8_t *buf,
> -                           int buf_size, int *buf_index)
> +static int get_last_needed_nal(H264Context *h)
>  {
> -    int i, nalsize = 0;
> -
> -    if (*buf_index >= buf_size - h->nal_length_size) {
> -        // the end of the buffer is reached, refill it.
> -        return AVERROR(EAGAIN);
> -    }
> -
> -    for (i = 0; i < h->nal_length_size; i++)
> -        nalsize = (nalsize << 8) | buf[(*buf_index)++];
> -    if (nalsize <= 0 || nalsize > buf_size - *buf_index) {
> -        av_log(h->avctx, AV_LOG_ERROR,
> -               "AVC: nal size %d\n", nalsize);
> -        return AVERROR_INVALIDDATA;
> -    }
> -    return nalsize;
> -}
> -
> -static int get_bit_length(H264Context *h, const uint8_t *buf,
> -                          const uint8_t *ptr, int dst_length,
> -                          int i, int next_avc)
> -{
> -    if ((h->workaround_bugs & FF_BUG_AUTODETECT) && i + 3 < next_avc &&
> -        buf[i]     == 0x00 && buf[i + 1] == 0x00 &&
> -        buf[i + 2] == 0x01 && buf[i + 3] == 0xE0)
> -        h->workaround_bugs |= FF_BUG_TRUNCATED;
> -
> -    if (!(h->workaround_bugs & FF_BUG_TRUNCATED))
> -        while (dst_length > 0 && ptr[dst_length - 1] == 0)
> -            dst_length--;
> -
> -    if (!dst_length)
> -        return 0;
> -
> -    return 8 * dst_length - decode_rbsp_trailing(h, ptr + dst_length - 1);
> -}
> -
> -static int get_last_needed_nal(H264Context *h, const uint8_t *buf, int 
> buf_size)
> -{
> -    int next_avc    = h->is_avc ? 0 : buf_size;
> -    int nal_index   = 0;
> -    int buf_index   = 0;
>      int nals_needed = 0;
> +    int i;
>  
> -    while(1) {
> +    for (i = 0; i < h->pkt.nb_nals; i++) {
> +        H2645NAL *nal = &h->pkt.nals[i];
>          GetBitContext gb;
> -        int nalsize = 0;
> -        int dst_length, bit_length, consumed;
> -        const uint8_t *ptr;
> -
> -        if (buf_index >= next_avc) {
> -            nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index);
> -            if (nalsize < 0)
> -                break;
> -            next_avc = buf_index + nalsize;
> -        } else {
> -            buf_index = find_start_code(buf, buf_size, buf_index, next_avc);
> -            if (buf_index >= buf_size)
> -                break;
> -        }
> -
> -        ptr = ff_h264_decode_nal(h, &h->slice_ctx[0], buf + buf_index, 
> &dst_length, &consumed,
> -                                 next_avc - buf_index);
> -
> -        if (!ptr || dst_length < 0)
> -            return AVERROR_INVALIDDATA;
> -
> -        buf_index += consumed;
> -
> -        bit_length = get_bit_length(h, buf, ptr, dst_length,
> -                                    buf_index, next_avc);
> -        nal_index++;
>  
>          /* packets can sometimes contain multiple PPS/SPS,
>           * e.g. two PAFF field pictures in one packet, or a demuxer
>           * which splits NALs strangely if so, when frame threading we
>           * can't start the next thread until we've read all of them */
> -        switch (h->nal_unit_type) {
> +        switch (nal->type) {
>          case NAL_SPS:
>          case NAL_PPS:
> -            nals_needed = nal_index;
> +            nals_needed = i;
>              break;
>          case NAL_DPA:
>          case NAL_IDR_SLICE:
>          case NAL_SLICE:
> -            init_get_bits(&gb, ptr, bit_length);
> +            init_get_bits(&gb, nal->data + 1, (nal->size - 1) * 8);
>              if (!get_ue_golomb(&gb))
> -                nals_needed = nal_index;
> +                nals_needed = i;
>          }
>      }
>  
> @@ -1401,13 +1300,9 @@ static int decode_nal_units(H264Context *h, const 
> uint8_t *buf, int buf_size,
>                              int parse_extradata)
>  {
>      AVCodecContext *const avctx = h->avctx;
> -    H264SliceContext *sl;
> -    int buf_index;
> -    unsigned context_count;
> -    int next_avc;
> +    unsigned context_count = 0;
>      int nals_needed = 0; ///< number of NALs that need decoding before the 
> next frame thread starts
> -    int nal_index;
> -    int ret = 0;
> +    int i, ret = 0;
>  
>      h->max_contexts = h->slice_context_count;
>      if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS)) {
> @@ -1417,199 +1312,157 @@ static int decode_nal_units(H264Context *h, const 
> uint8_t *buf, int buf_size,
>          ff_h264_reset_sei(h);
>      }
>  
> -    if (avctx->active_thread_type & FF_THREAD_FRAME)
> -        nals_needed = get_last_needed_nal(h, buf, buf_size);
> -
> -    {
> -        buf_index     = 0;
> -        context_count = 0;
> -        next_avc      = h->is_avc ? 0 : buf_size;
> -        nal_index     = 0;
> -        for (;;) {
> -            int consumed;
> -            int dst_length;
> -            int bit_length;
> -            const uint8_t *ptr;
> -            int nalsize = 0;
> -            int err;
> -
> -            if (buf_index >= next_avc) {
> -                nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index);
> -                if (nalsize < 0)
> -                    break;
> -                next_avc = buf_index + nalsize;
> -            } else {
> -                buf_index = find_start_code(buf, buf_size, buf_index, 
> next_avc);
> -                if (buf_index >= buf_size)
> -                    break;
> -                if (buf_index >= next_avc)
> -                    continue;
> -            }
> +    ret = ff_h2645_packet_split(&h->pkt, buf, buf_size, avctx, h->is_avc,
> +                                h->nal_length_size, avctx->codec_id);
> +    if (ret < 0) {
> +        av_log(avctx, AV_LOG_ERROR,
> +               "Error splitting the input into NAL units.\n");
> +        return ret;
> +    }
>  
> -            sl = &h->slice_ctx[context_count];
> +    if (avctx->active_thread_type & FF_THREAD_FRAME)
> +        nals_needed = get_last_needed_nal(h);
>  
> -            ptr = ff_h264_decode_nal(h, sl, buf + buf_index, &dst_length,
> -                                     &consumed, next_avc - buf_index);
> -            if (!ptr || dst_length < 0) {
> -                ret = -1;
> -                goto end;
> -            }
> +    for (i = 0; i < h->pkt.nb_nals; i++) {
> +        H2645NAL *nal = &h->pkt.nals[i];
> +        H264SliceContext *sl = &h->slice_ctx[context_count];
> +        int err;
>  
> -            bit_length = get_bit_length(h, buf, ptr, dst_length,
> -                                        buf_index + consumed, next_avc);
> +        if (avctx->skip_frame >= AVDISCARD_NONREF &&
> +            nal->ref_idc == 0 && nal->type != NAL_SEI)
> +            continue;
>  
> -            if (h->avctx->debug & FF_DEBUG_STARTCODE)
> -                av_log(h->avctx, AV_LOG_DEBUG,
> -                       "NAL %d at %d/%d length %d\n",
> -                       h->nal_unit_type, buf_index, buf_size, dst_length);
> +        // FIXME these should stop being context-global variables
> +        h->nal_ref_idc   = nal->ref_idc;
> +        h->nal_unit_type = nal->type;
>  
> -            if (h->is_avc && (nalsize != consumed) && nalsize)
> -                av_log(h->avctx, AV_LOG_DEBUG,
> -                       "AVC: Consumed only %d bytes instead of %d\n",
> -                       consumed, nalsize);
> +again:
> +        /* Ignore every NAL unit type except PPS and SPS during extradata
> +         * parsing. Decoding slices is not possible in codec init
> +         * with frame-mt */
> +        if (parse_extradata && HAVE_THREADS &&
> +            (h->avctx->active_thread_type & FF_THREAD_FRAME) &&
> +            (nal->type != NAL_PPS && nal->type != NAL_SPS)) {
> +            if (nal->type < NAL_AUD || nal->type > NAL_AUXILIARY_SLICE)
> +                av_log(avctx, AV_LOG_INFO,
> +                       "Ignoring NAL unit %d during extradata parsing\n",
> +                       h->nal_unit_type);

using nal->type as argument in the av_log would be better

> +            nal->type = NAL_FF_IGNORE;

I don't think it is used anywhere but to keep the old behaviour you 
should set h->nal_unit_type NAL_FF_IGNORE too. I would just move the 
setting of h->nal_ref_idc and h->nal_unit_type below this block.

> +        }
>  
> -            buf_index += consumed;
> -            nal_index++;
> +        err = 0;
> +        switch (nal->type) {
> +        case NAL_IDR_SLICE:
> +            if (nal->type != NAL_IDR_SLICE) {

this looks like it will be always false, not changed by this commit but 
in 51d8725a6e4c7f989d6f0f38b59cb54a2d72846c

looks fine otherwise

Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to