Skip to content
Snippets Groups Projects
h264.c 213 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
     * Process a macroblock; this case avoids checks for expensive uncommon cases.
     */
    static void hl_decode_mb_simple(H264Context *h){
        hl_decode_mb_internal(h, 1);
    }
    
    /**
     * Process a macroblock; this handles edge cases, such as interlacing.
     */
    static void av_noinline hl_decode_mb_complex(H264Context *h){
        hl_decode_mb_internal(h, 0);
    }
    
    
    void ff_h264_hl_decode_mb(H264Context *h){
    
        const int mb_type= s->current_picture.mb_type[mb_xy];
    
        int is_complex = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0;
    
    static int pred_weight_table(H264Context *h){
        MpegEncContext * const s = &h->s;
        int list, i;
    
        int luma_def, chroma_def;
    
        h->use_weight= 0;
        h->use_weight_chroma= 0;
    
        h->luma_log2_weight_denom= get_ue_golomb(&s->gb);
        h->chroma_log2_weight_denom= get_ue_golomb(&s->gb);
    
        luma_def = 1<<h->luma_log2_weight_denom;
        chroma_def = 1<<h->chroma_log2_weight_denom;
    
    
        for(list=0; list<2; list++){
    
            h->luma_weight_flag[list]   = 0;
            h->chroma_weight_flag[list] = 0;
    
            for(i=0; i<h->ref_count[list]; i++){
                int luma_weight_flag, chroma_weight_flag;
    
                luma_weight_flag= get_bits1(&s->gb);
                if(luma_weight_flag){
                    h->luma_weight[list][i]= get_se_golomb(&s->gb);
                    h->luma_offset[list][i]= get_se_golomb(&s->gb);
    
                    if(   h->luma_weight[list][i] != luma_def
    
                       || h->luma_offset[list][i] != 0) {
    
                        h->use_weight= 1;
    
                }else{
                    h->luma_weight[list][i]= luma_def;
                    h->luma_offset[list][i]= 0;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    chroma_weight_flag= get_bits1(&s->gb);
                    if(chroma_weight_flag){
                        int j;
                        for(j=0; j<2; j++){
                            h->chroma_weight[list][i][j]= get_se_golomb(&s->gb);
                            h->chroma_offset[list][i][j]= get_se_golomb(&s->gb);
                            if(   h->chroma_weight[list][i][j] != chroma_def
    
                               || h->chroma_offset[list][i][j] != 0) {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                                h->use_weight_chroma= 1;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                        }
                    }else{
                        int j;
                        for(j=0; j<2; j++){
                            h->chroma_weight[list][i][j]= chroma_def;
                            h->chroma_offset[list][i][j]= 0;
                        }
    
            if(h->slice_type_nos != FF_B_TYPE) break;
    
        h->use_weight= h->use_weight || h->use_weight_chroma;
    
    static void implicit_weight_table(H264Context *h){
        MpegEncContext * const s = &h->s;
    
        int cur_poc = s->current_picture_ptr->poc;
    
    
        for (i = 0; i < 2; i++) {
            h->luma_weight_flag[i]   = 0;
            h->chroma_weight_flag[i] = 0;
        }
    
    
        if(   h->ref_count[0] == 1 && h->ref_count[1] == 1
           && h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2*cur_poc){
            h->use_weight= 0;
            h->use_weight_chroma= 0;
            return;
        }
    
        h->use_weight= 2;
        h->use_weight_chroma= 2;
        h->luma_log2_weight_denom= 5;
        h->chroma_log2_weight_denom= 5;
    
        for(ref0=0; ref0 < h->ref_count[0]; ref0++){
            int poc0 = h->ref_list[0][ref0].poc;
            for(ref1=0; ref1 < h->ref_count[1]; ref1++){
    
                int poc1 = h->ref_list[1][ref1].poc;
    
                int td = av_clip(poc1 - poc0, -128, 127);
    
                if(td){
    
                    int tb = av_clip(cur_poc - poc0, -128, 127);
    
                    int tx = (16384 + (FFABS(td) >> 1)) / td;
    
                    int dist_scale_factor = av_clip((tb*tx + 32) >> 6, -1024, 1023) >> 2;
    
                    if(dist_scale_factor < -64 || dist_scale_factor > 128)
                        h->implicit_weight[ref0][ref1] = 32;
                    else
                        h->implicit_weight[ref0][ref1] = 64 - dist_scale_factor;
                }else
                    h->implicit_weight[ref0][ref1] = 32;
            }
        }
    }
    
    
    Loic Le Loarer's avatar
    Loic Le Loarer committed
     * instantaneous decoder refresh.
    
     */
    static void idr(H264Context *h){
    
        ff_h264_remove_all_refs(h);
    
        h->prev_frame_num_offset= 0;
        h->prev_poc_msb=
        h->prev_poc_lsb= 0;
    
    /* forget old pics after a seek */
    static void flush_dpb(AVCodecContext *avctx){
        H264Context *h= avctx->priv_data;
        int i;
    
        for(i=0; i<MAX_DELAYED_PIC_COUNT; i++) {
    
            if(h->delayed_pic[i])
                h->delayed_pic[i]->reference= 0;
    
            h->delayed_pic[i]= NULL;
    
        idr(h);
    
        if(h->s.current_picture_ptr)
            h->s.current_picture_ptr->reference= 0;
    
        ff_h264_reset_sei(h);
    
    static int init_poc(H264Context *h){
        MpegEncContext * const s = &h->s;
        const int max_frame_num= 1<<h->sps.log2_max_frame_num;
        int field_poc[2];
    
        Picture *cur = s->current_picture_ptr;
    
        h->frame_num_offset= h->prev_frame_num_offset;
    
        if(h->frame_num < h->prev_frame_num)
    
            h->frame_num_offset += max_frame_num;
    
    
        if(h->sps.poc_type==0){
            const int max_poc_lsb= 1<<h->sps.log2_max_poc_lsb;
    
            if     (h->poc_lsb < h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb >= max_poc_lsb/2)
                h->poc_msb = h->prev_poc_msb + max_poc_lsb;
            else if(h->poc_lsb > h->prev_poc_lsb && h->prev_poc_lsb - h->poc_lsb < -max_poc_lsb/2)
                h->poc_msb = h->prev_poc_msb - max_poc_lsb;
            else
                h->poc_msb = h->prev_poc_msb;
    //printf("poc: %d %d\n", h->poc_msb, h->poc_lsb);
    
            field_poc[1] = h->poc_msb + h->poc_lsb;
    
            if(s->picture_structure == PICT_FRAME)
    
                field_poc[1] += h->delta_poc_bottom;
        }else if(h->sps.poc_type==1){
            int abs_frame_num, expected_delta_per_poc_cycle, expectedpoc;
            int i;
    
            if(h->sps.poc_cycle_length != 0)
                abs_frame_num = h->frame_num_offset + h->frame_num;
            else
                abs_frame_num = 0;
    
            if(h->nal_ref_idc==0 && abs_frame_num > 0)
                abs_frame_num--;
    
            expected_delta_per_poc_cycle = 0;
            for(i=0; i < h->sps.poc_cycle_length; i++)
                expected_delta_per_poc_cycle += h->sps.offset_for_ref_frame[ i ]; //FIXME integrate during sps parse
    
            if(abs_frame_num > 0){
                int poc_cycle_cnt          = (abs_frame_num - 1) / h->sps.poc_cycle_length;
                int frame_num_in_poc_cycle = (abs_frame_num - 1) % h->sps.poc_cycle_length;
    
                expectedpoc = poc_cycle_cnt * expected_delta_per_poc_cycle;
                for(i = 0; i <= frame_num_in_poc_cycle; i++)
                    expectedpoc = expectedpoc + h->sps.offset_for_ref_frame[ i ];
            } else
                expectedpoc = 0;
    
    
            if(h->nal_ref_idc == 0)
    
                expectedpoc = expectedpoc + h->sps.offset_for_non_ref_pic;
    
            field_poc[0] = expectedpoc + h->delta_poc[0];
            field_poc[1] = field_poc[0] + h->sps.offset_for_top_to_bottom_field;
    
            if(s->picture_structure == PICT_FRAME)
                field_poc[1] += h->delta_poc[1];
        }else{
    
            int poc= 2*(h->frame_num_offset + h->frame_num);
    
            if(!h->nal_ref_idc)
                poc--;
    
            field_poc[0]= poc;
            field_poc[1]= poc;
        }
    
        if(s->picture_structure != PICT_BOTTOM_FIELD)
    
            s->current_picture_ptr->field_poc[0]= field_poc[0];
    
        if(s->picture_structure != PICT_TOP_FIELD)
    
            s->current_picture_ptr->field_poc[1]= field_poc[1];
    
        cur->poc= FFMIN(cur->field_poc[0], cur->field_poc[1]);
    
    
    /**
     * initialize scan tables
     */
    static void init_scan_tables(H264Context *h){
        MpegEncContext * const s = &h->s;
        int i;
        if(s->dsp.h264_idct_add == ff_h264_idct_add_c){ //FIXME little ugly
            memcpy(h->zigzag_scan, zigzag_scan, 16*sizeof(uint8_t));
            memcpy(h-> field_scan,  field_scan, 16*sizeof(uint8_t));
        }else{
            for(i=0; i<16; i++){
    #define T(x) (x>>2) | ((x<<2) & 0xF)
                h->zigzag_scan[i] = T(zigzag_scan[i]);
                h-> field_scan[i] = T( field_scan[i]);
    #undef T
            }
        }
        if(s->dsp.h264_idct8_add == ff_h264_idct8_add_c){
    
            memcpy(h->zigzag_scan8x8,       ff_zigzag_direct,     64*sizeof(uint8_t));
    
            memcpy(h->zigzag_scan8x8_cavlc, zigzag_scan8x8_cavlc, 64*sizeof(uint8_t));
            memcpy(h->field_scan8x8,        field_scan8x8,        64*sizeof(uint8_t));
            memcpy(h->field_scan8x8_cavlc,  field_scan8x8_cavlc,  64*sizeof(uint8_t));
        }else{
            for(i=0; i<64; i++){
    #define T(x) (x>>3) | ((x&7)<<3)
    
                h->zigzag_scan8x8[i]       = T(ff_zigzag_direct[i]);
    
                h->zigzag_scan8x8_cavlc[i] = T(zigzag_scan8x8_cavlc[i]);
                h->field_scan8x8[i]        = T(field_scan8x8[i]);
                h->field_scan8x8_cavlc[i]  = T(field_scan8x8_cavlc[i]);
    #undef T
            }
        }
        if(h->sps.transform_bypass){ //FIXME same ugly
            h->zigzag_scan_q0          = zigzag_scan;
    
            h->zigzag_scan8x8_q0       = ff_zigzag_direct;
    
            h->zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc;
            h->field_scan_q0           = field_scan;
            h->field_scan8x8_q0        = field_scan8x8;
            h->field_scan8x8_cavlc_q0  = field_scan8x8_cavlc;
        }else{
            h->zigzag_scan_q0          = h->zigzag_scan;
            h->zigzag_scan8x8_q0       = h->zigzag_scan8x8;
            h->zigzag_scan8x8_cavlc_q0 = h->zigzag_scan8x8_cavlc;
            h->field_scan_q0           = h->field_scan;
            h->field_scan8x8_q0        = h->field_scan8x8;
            h->field_scan8x8_cavlc_q0  = h->field_scan8x8_cavlc;
        }
    }
    
    static void field_end(H264Context *h){
        MpegEncContext * const s = &h->s;
        AVCodecContext * const avctx= s->avctx;
        s->mb_y= 0;
    
        s->current_picture_ptr->qscale_type= FF_QSCALE_TYPE_H264;
        s->current_picture_ptr->pict_type= s->pict_type;
    
        if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
            ff_vdpau_h264_set_reference_frames(s);
    
        if(!s->dropable) {
    
            ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
    
            h->prev_poc_msb= h->poc_msb;
            h->prev_poc_lsb= h->poc_lsb;
        }
        h->prev_frame_num_offset= h->frame_num_offset;
        h->prev_frame_num= h->frame_num;
    
        if (avctx->hwaccel) {
            if (avctx->hwaccel->end_frame(avctx) < 0)
                av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
        }
    
        if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
            ff_vdpau_h264_picture_complete(s);
    
        /*
         * FIXME: Error handling code does not seem to support interlaced
         * when slices span multiple rows
         * The ff_er_add_slice calls don't work right for bottom
         * fields; they cause massive erroneous error concealing
         * Error marking covers both fields (top and bottom).
         * This causes a mismatched s->error_count
         * and a bad error table. Further, the error count goes to
         * INT_MAX when called for bottom field, because mb_y is
         * past end by one (callers fault) and resync_mb_y != 0
         * causes problems for the first MB line, too.
         */
        if (!FIELD_PICTURE)
            ff_er_frame_end(s);
    
        MPV_frame_end(s);
    
    /**
     * Replicates H264 "master" context to thread contexts.
     */
    static void clone_slice(H264Context *dst, H264Context *src)
    {
        memcpy(dst->block_offset,     src->block_offset, sizeof(dst->block_offset));
        dst->s.current_picture_ptr  = src->s.current_picture_ptr;
        dst->s.current_picture      = src->s.current_picture;
        dst->s.linesize             = src->s.linesize;
        dst->s.uvlinesize           = src->s.uvlinesize;
    
        dst->s.first_field          = src->s.first_field;
    
    
        dst->prev_poc_msb           = src->prev_poc_msb;
        dst->prev_poc_lsb           = src->prev_poc_lsb;
        dst->prev_frame_num_offset  = src->prev_frame_num_offset;
        dst->prev_frame_num         = src->prev_frame_num;
        dst->short_ref_count        = src->short_ref_count;
    
        memcpy(dst->short_ref,        src->short_ref,        sizeof(dst->short_ref));
        memcpy(dst->long_ref,         src->long_ref,         sizeof(dst->long_ref));
        memcpy(dst->default_ref_list, src->default_ref_list, sizeof(dst->default_ref_list));
        memcpy(dst->ref_list,         src->ref_list,         sizeof(dst->ref_list));
    
    
        memcpy(dst->dequant4_coeff,   src->dequant4_coeff,   sizeof(src->dequant4_coeff));
        memcpy(dst->dequant8_coeff,   src->dequant8_coeff,   sizeof(src->dequant8_coeff));
    
    /**
     * decodes a slice header.
    
     * This will also call MPV_common_init() and frame_start() as needed.
    
     *
     * @param h h264context
     * @param h0 h264 master context (differs from 'h' when doing sliced based parallel decoding)
     *
    
     * @return 0 if okay, <0 if an error occurred, 1 if decoding must not be multithreaded
    
    static int decode_slice_header(H264Context *h, H264Context *h0){
    
        MpegEncContext * const s = &h->s;
    
        unsigned int first_mb_in_slice;
    
        int num_ref_idx_active_override_flag;
    
        unsigned int slice_type, tmp, i, j;
    
        if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc){
            s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab;
            s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab;
        }else{
            s->me.qpel_put= s->dsp.put_h264_qpel_pixels_tab;
            s->me.qpel_avg= s->dsp.avg_h264_qpel_pixels_tab;
        }
    
    
        first_mb_in_slice= get_ue_golomb(&s->gb);
    
    
        if(first_mb_in_slice == 0){ //FIXME better field boundary detection
            if(h0->current_slice && FIELD_PICTURE){
                field_end(h);
            }
    
    
            h0->current_slice = 0;
    
    Andreas Öman's avatar
    Andreas Öman committed
                s->current_picture_ptr= NULL;
    
        slice_type= get_ue_golomb_31(&s->gb);
    
            av_log(h->s.avctx, AV_LOG_ERROR, "slice type too large (%d) at %d %d\n", h->slice_type, s->mb_x, s->mb_y);
    
    Loic Le Loarer's avatar
    Loic Le Loarer committed
            return -1;
    
            h->slice_type_fixed=1;
        }else
            h->slice_type_fixed=0;
    
        slice_type= golomb_to_pict_type[ slice_type ];
    
        if (slice_type == FF_I_TYPE
    
            || (h0->current_slice != 0 && slice_type == h0->last_slice_type) ) {
    
            default_ref_list_done = 1;
        }
        h->slice_type= slice_type;
    
        h->slice_type_nos= slice_type & 3;
    
        s->pict_type= h->slice_type; // to make a few old functions happy, it's wrong though
    
        if (s->pict_type == FF_B_TYPE && s0->last_picture_ptr == NULL) {
    
            av_log(h->s.avctx, AV_LOG_ERROR,
                   "B picture before any references, skipping\n");
            return -1;
        }
    
        pps_id= get_ue_golomb(&s->gb);
    
            av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
    
            return -1;
        }
    
        if(!h0->pps_buffers[pps_id]) {
    
            av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS %u referenced\n", pps_id);
    
        h->pps= *h0->pps_buffers[pps_id];
    
        if(!h0->sps_buffers[h->pps.sps_id]) {
    
            av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h->pps.sps_id);
    
        h->sps = *h0->sps_buffers[h->pps.sps_id];
    
        if(h == h0 && h->dequant_coeff_pps != pps_id){
    
            h->dequant_coeff_pps = pps_id;
    
            init_dequant_tables(h);
        }
    
        s->mb_width= h->sps.mb_width;
    
        s->mb_height= h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
    
        h->b_stride=  s->mb_width*4;
        h->b8_stride= s->mb_width*2;
    
        s->width = 16*s->mb_width - 2*FFMIN(h->sps.crop_right, 7);
    
        if(h->sps.frame_mbs_only_flag)
    
            s->height= 16*s->mb_height - 2*FFMIN(h->sps.crop_bottom, 7);
    
            s->height= 16*s->mb_height - 4*FFMIN(h->sps.crop_bottom, 3);
    
    
        if (s->context_initialized
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            && (   s->width != s->avctx->width || s->height != s->avctx->height)) {
    
            if(h != h0)
                return -1;   // width / height changed during parallelized decoding
    
            free_tables(h);
    
            MPV_common_end(s);
        }
        if (!s->context_initialized) {
    
            if(h != h0)
                return -1;  // we cant (re-)initialize context during parallel decoding
    
    
            avcodec_set_dimensions(s->avctx, s->width, s->height);
            s->avctx->sample_aspect_ratio= h->sps.sar;
            if(!s->avctx->sample_aspect_ratio.den)
                s->avctx->sample_aspect_ratio.den = 1;
    
    
            if(h->sps.video_signal_type_present_flag){
                s->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
                if(h->sps.colour_description_present_flag){
                    s->avctx->color_primaries = h->sps.color_primaries;
                    s->avctx->color_trc       = h->sps.color_trc;
                    s->avctx->colorspace      = h->sps.colorspace;
                }
            }
    
    
            if(h->sps.timing_info_present_flag){
                s->avctx->time_base= (AVRational){h->sps.num_units_in_tick, h->sps.time_scale};
                if(h->x264_build > 0 && h->x264_build < 44)
                    s->avctx->time_base.den *= 2;
                av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,
                          s->avctx->time_base.num, s->avctx->time_base.den, 1<<30);
            }
            s->avctx->pix_fmt = s->avctx->get_format(s->avctx, s->avctx->codec->pix_fmts);
            s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt);
    
    
            if (MPV_common_init(s) < 0)
                return -1;
    
            ff_h264_alloc_tables(h);
    
            for(i = 1; i < s->avctx->thread_count; i++) {
                H264Context *c;
                c = h->thread_context[i] = av_malloc(sizeof(H264Context));
    
                memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext));
    
                memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));
                c->sps = h->sps;
                c->pps = h->pps;
                init_scan_tables(c);
                clone_tables(c, h);
            }
    
            for(i = 0; i < s->avctx->thread_count; i++)
                if(context_init(h->thread_context[i]) < 0)
                    return -1;
    
        }
    
        h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num);
    
    
        h->mb_mbaff = 0;
    
        last_pic_structure = s0->picture_structure;
    
        if(h->sps.frame_mbs_only_flag){
            s->picture_structure= PICT_FRAME;
        }else{
    
            if(get_bits1(&s->gb)) { //field_pic_flag
    
                s->picture_structure= PICT_TOP_FIELD + get_bits1(&s->gb); //bottom_field_flag
    
                s->picture_structure= PICT_FRAME;
    
        h->mb_field_decoding_flag= s->picture_structure != PICT_FRAME;
    
            while(h->frame_num !=  h->prev_frame_num &&
                  h->frame_num != (h->prev_frame_num+1)%(1<<h->sps.log2_max_frame_num)){
                av_log(NULL, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num);
    
                if (ff_h264_frame_start(h) < 0)
    
                h->prev_frame_num++;
                h->prev_frame_num %= 1<<h->sps.log2_max_frame_num;
                s->current_picture_ptr->frame_num= h->prev_frame_num;
    
                ff_h264_execute_ref_pic_marking(h, NULL, 0);
    
            /* See if we have a decoded first field looking for a pair... */
            if (s0->first_field) {
                assert(s0->current_picture_ptr);
                assert(s0->current_picture_ptr->data[0]);
                assert(s0->current_picture_ptr->reference != DELAYED_PIC_REF);
    
                /* figure out if we have a complementary field pair */
                if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
                    /*
                     * Previous field is unmatched. Don't display it, but let it
                     * remain for reference if marked as such.
                     */
                    s0->current_picture_ptr = NULL;
                    s0->first_field = FIELD_PICTURE;
    
                } else {
                    if (h->nal_ref_idc &&
                            s0->current_picture_ptr->reference &&
                            s0->current_picture_ptr->frame_num != h->frame_num) {
                        /*
                         * This and previous field were reference, but had
                         * different frame_nums. Consider this field first in
                         * pair. Throw away previous field except for reference
                         * purposes.
                         */
                        s0->first_field = 1;
                        s0->current_picture_ptr = NULL;
    
                    } else {
                        /* Second field in complementary pair */
                        s0->first_field = 0;
                    }
                }
    
            } else {
                /* Frame or first field in a potentially complementary pair */
                assert(!s0->current_picture_ptr);
                s0->first_field = FIELD_PICTURE;
            }
    
    
            if((!FIELD_PICTURE || s0->first_field) && ff_h264_frame_start(h) < 0) {
    
        }
        if(h != h0)
            clone_slice(h, h0);
    
        s->current_picture_ptr->frame_num= h->frame_num; //FIXME frame_num cleanup
    
    
        assert(s->mb_num == s->mb_width * s->mb_height);
    
        if(first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= s->mb_num ||
    
           first_mb_in_slice                    >= s->mb_num){
            av_log(h->s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
            return -1;
        }
    
        s->resync_mb_x = s->mb_x = first_mb_in_slice % s->mb_width;
    
        s->resync_mb_y = s->mb_y = (first_mb_in_slice / s->mb_width) << FIELD_OR_MBAFF_PICTURE;
        if (s->picture_structure == PICT_BOTTOM_FIELD)
            s->resync_mb_y = s->mb_y = s->mb_y + 1;
    
        assert(s->mb_y < s->mb_height);
    
        if(s->picture_structure==PICT_FRAME){
            h->curr_pic_num=   h->frame_num;
            h->max_pic_num= 1<< h->sps.log2_max_frame_num;
        }else{
    
            h->curr_pic_num= 2*h->frame_num + 1;
    
            h->max_pic_num= 1<<(h->sps.log2_max_frame_num + 1);
        }
    
        if(h->nal_unit_type == NAL_IDR_SLICE){
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            get_ue_golomb(&s->gb); /* idr_pic_id */
    
        if(h->sps.poc_type==0){
            h->poc_lsb= get_bits(&s->gb, h->sps.log2_max_poc_lsb);
    
            if(h->pps.pic_order_present==1 && s->picture_structure==PICT_FRAME){
                h->delta_poc_bottom= get_se_golomb(&s->gb);
            }
        }
    
        if(h->sps.poc_type==1 && !h->sps.delta_pic_order_always_zero_flag){
            h->delta_poc[0]= get_se_golomb(&s->gb);
    
            if(h->pps.pic_order_present==1 && s->picture_structure==PICT_FRAME)
                h->delta_poc[1]= get_se_golomb(&s->gb);
        }
    
        init_poc(h);
    
        if(h->pps.redundant_pic_cnt_present){
            h->redundant_pic_count= get_ue_golomb(&s->gb);
        }
    
    
        //set defaults, might be overridden a few lines later
    
        h->ref_count[0]= h->pps.ref_count[0];
        h->ref_count[1]= h->pps.ref_count[1];
    
    
        if(h->slice_type_nos != FF_I_TYPE){
    
                h->direct_spatial_mv_pred= get_bits1(&s->gb);
            }
            num_ref_idx_active_override_flag= get_bits1(&s->gb);
    
            if(num_ref_idx_active_override_flag){
                h->ref_count[0]= get_ue_golomb(&s->gb) + 1;
    
                    h->ref_count[1]= get_ue_golomb(&s->gb) + 1;
    
    
                if(h->ref_count[0]-1 > 32-1 || h->ref_count[1]-1 > 32-1){
    
                    av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
    
                    h->ref_count[0]= h->ref_count[1]= 1;
    
                h->list_count= 2;
            else
                h->list_count= 1;
        }else
            h->list_count= 0;
    
            ff_h264_fill_default_ref_list(h);
    
        if(h->slice_type_nos!=FF_I_TYPE && ff_h264_decode_ref_pic_list_reordering(h) < 0)
    
        if(h->slice_type_nos!=FF_I_TYPE){
            s->last_picture_ptr= &h->ref_list[0][0];
    
            ff_copy_picture(&s->last_picture, s->last_picture_ptr);
    
        }
        if(h->slice_type_nos==FF_B_TYPE){
            s->next_picture_ptr= &h->ref_list[1][0];
    
            ff_copy_picture(&s->next_picture, s->next_picture_ptr);
    
        if(   (h->pps.weighted_pred          && h->slice_type_nos == FF_P_TYPE )
    
           ||  (h->pps.weighted_bipred_idc==1 && h->slice_type_nos== FF_B_TYPE ) )
    
            pred_weight_table(h);
    
        else if(h->pps.weighted_bipred_idc==2 && h->slice_type_nos== FF_B_TYPE)
    
            implicit_weight_table(h);
    
            h->use_weight = 0;
    
            for (i = 0; i < 2; i++) {
                h->luma_weight_flag[i]   = 0;
                h->chroma_weight_flag[i] = 0;
            }
        }
    
            ff_h264_decode_ref_pic_marking(h0, &s->gb);
    
        if(FRAME_MBAFF)
    
            ff_h264_fill_mbaff_ref_list(h);
    
        if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred)
    
            ff_h264_direct_dist_scale_factor(h);
        ff_h264_direct_ref_list_init(h);
    
        if( h->slice_type_nos != FF_I_TYPE && h->pps.cabac ){
    
            if(tmp > 2){
                av_log(s->avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
                return -1;
            }
            h->cabac_init_idc= tmp;
        }
    
        tmp = h->pps.init_qp + get_se_golomb(&s->gb);
        if(tmp>51){
            av_log(s->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
    
        h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
        h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
    
        //FIXME qscale / qp ... stuff
    
        if(h->slice_type == FF_SP_TYPE){
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            get_bits1(&s->gb); /* sp_for_switch_flag */
    
        if(h->slice_type==FF_SP_TYPE || h->slice_type == FF_SI_TYPE){
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            get_se_golomb(&s->gb); /* slice_qs_delta */
    
        h->slice_alpha_c0_offset = 0;
        h->slice_beta_offset = 0;
    
        if( h->pps.deblocking_filter_parameters_present ) {
    
            if(tmp > 2){
                av_log(s->avctx, AV_LOG_ERROR, "deblocking_filter_idc %u out of range\n", tmp);
                return -1;
            }
            h->deblocking_filter= tmp;
    
            if(h->deblocking_filter < 2)
    
                h->slice_alpha_c0_offset = get_se_golomb(&s->gb) << 1;
                h->slice_beta_offset = get_se_golomb(&s->gb) << 1;
    
        if(   s->avctx->skip_loop_filter >= AVDISCARD_ALL
    
           ||(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && h->slice_type_nos != FF_I_TYPE)
    
           ||(s->avctx->skip_loop_filter >= AVDISCARD_BIDIR  && h->slice_type_nos == FF_B_TYPE)
    
           ||(s->avctx->skip_loop_filter >= AVDISCARD_NONREF && h->nal_ref_idc == 0))
            h->deblocking_filter= 0;
    
    
        if(h->deblocking_filter == 1 && h0->max_contexts > 1) {
    
            if(s->avctx->flags2 & CODEC_FLAG2_FAST) {
                /* Cheat slightly for speed:
    
                   Do not bother to deblock across slices. */
    
                h->deblocking_filter = 2;
            } else {
    
    Andreas Öman's avatar
    Andreas Öman committed
                h0->max_contexts = 1;
                if(!h0->single_decode_warning) {
                    av_log(s->avctx, AV_LOG_INFO, "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n");
                    h0->single_decode_warning = 1;
                }
                if(h != h0)
                    return 1; // deblocking switched inside frame
    
    #if 0 //FMO
        if( h->pps.num_slice_groups > 1  && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5)
            slice_group_change_cycle= get_bits(&s->gb, ?);
    #endif
    
    
        h0->last_slice_type = slice_type;
        h->slice_num = ++h0->current_slice;
    
        if(h->slice_num >= MAX_SLICES){
            av_log(s->avctx, AV_LOG_ERROR, "Too many slices, increase MAX_SLICES and recompile\n");
        }
    
            int *ref2frm= h->ref2frm[h->slice_num&(MAX_SLICES-1)][j];
    
            ref2frm[0]=
            ref2frm[1]= -1;
    
                ref2frm[i+2]= 4*h->ref_list[j][i].frame_num
                              +(h->ref_list[j][i].reference&3);
    
            ref2frm[18+0]=
            ref2frm[18+1]= -1;
            for(i=16; i<48; i++)
                ref2frm[i+4]= 4*h->ref_list[j][i].frame_num
                              +(h->ref_list[j][i].reference&3);
    
        h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16;
    
        h->emu_edge_height= (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        s->avctx->refs= h->sps.ref_frame_count;
    
    
        if(s->avctx->debug&FF_DEBUG_PICT_INFO){
    
            av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
    
                   h->slice_num,
                   (s->picture_structure==PICT_FRAME ? "F" : s->picture_structure==PICT_TOP_FIELD ? "T" : "B"),
    
                   first_mb_in_slice,
    
                   av_get_pict_type_char(h->slice_type), h->slice_type_fixed ? " fix" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",
    
                   pps_id, h->frame_num,
                   s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1],
                   h->ref_count[0], h->ref_count[1],
                   s->qscale,
    
                   h->deblocking_filter, h->slice_alpha_c0_offset/2, h->slice_beta_offset/2,
    
                   h->use_weight,
    
                   h->use_weight==1 && h->use_weight_chroma ? "c" : "",
                   h->slice_type == FF_B_TYPE ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : ""
    
    int ff_h264_get_slice_type(H264Context *h)
    {
        switch (h->slice_type) {
        case FF_P_TYPE:  return 0;
        case FF_B_TYPE:  return 1;
        case FF_I_TYPE:  return 2;
        case FF_SP_TYPE: return 3;
        case FF_SI_TYPE: return 4;
        default:         return -1;
        }
    }
    
    
    /**
     *
     */
    static inline int get_level_prefix(GetBitContext *gb){
        unsigned int buf;
        int log;
    
        OPEN_READER(re, gb);
        UPDATE_CACHE(re, gb);
        buf=GET_CACHE(re, gb);
    
        log= 32 - av_log2(buf);
    #ifdef TRACE
        print_bin(buf>>(32-log), log);
    
        av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d lpr @%5d in %s get_level_prefix\n", buf>>(32-log), log, log-1, get_bits_count(gb), __FILE__);
    
    #endif
    
        LAST_SKIP_BITS(re, gb, log);
        CLOSE_READER(re, gb);
    
        return log-1;
    }
    
    
    static inline int get_dct8x8_allowed(H264Context *h){
    
        if(h->sps.direct_8x8_inference_flag)
            return !(*(uint64_t*)h->sub_mb_type & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8                )*0x0001000100010001ULL));
        else
            return !(*(uint64_t*)h->sub_mb_type & ((MB_TYPE_16x8|MB_TYPE_8x16|MB_TYPE_8x8|MB_TYPE_DIRECT2)*0x0001000100010001ULL));
    
    /**
     * decodes a residual block.
     * @param n block index
     * @param scantable scantable
     * @param max_coeff number of coefficients in the block
    
     * @return <0 if an error occurred
    
    static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff){
    
        MpegEncContext * const s = &h->s;
        static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
    
        int level[16];
        int zeros_left, coeff_num, coeff_token, total_coeff, i, j, trailing_ones, run_before;
    
    
        //FIXME put trailing_onex into the context
    
        if(n == CHROMA_DC_BLOCK_INDEX){
            coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
            total_coeff= coeff_token>>2;
    
            if(n == LUMA_DC_BLOCK_INDEX){
                total_coeff= pred_non_zero_count(h, 0);
                coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
                total_coeff= coeff_token>>2;
            }else{
                total_coeff= pred_non_zero_count(h, n);
                coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
                total_coeff= coeff_token>>2;
                h->non_zero_count_cache[ scan8[n] ]= total_coeff;
            }
        }
    
        //FIXME set last_non_zero?
    
        if(total_coeff==0)
            return 0;
    
        if(total_coeff > (unsigned)max_coeff) {
            av_log(h->s.avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", s->mb_x, s->mb_y, total_coeff);
    
        trailing_ones= coeff_token&3;
    
        tprintf(h->s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
    
        assert(total_coeff<=16);
    
        i = show_bits(gb, 3);
        skip_bits(gb, trailing_ones);
        level[0] = 1-((i&4)>>1);
        level[1] = 1-((i&2)   );
        level[2] = 1-((i&1)<<1);
    
            int suffix_length = total_coeff > 10 && trailing_ones < 3;
    
            int bitsi= show_bits(gb, LEVEL_TAB_BITS);
            int level_code= cavlc_level_tab[suffix_length][bitsi][0];
    
            skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]);
            if(level_code >= 100){
                prefix= level_code - 100;
                if(prefix == LEVEL_TAB_BITS)
                    prefix += get_level_prefix(gb);
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                //first coefficient has suffix_length equal to 0 or 1
                if(prefix<14){ //FIXME try to build a large unified VLC table for all this
                    if(suffix_length)
    
                        level_code= (prefix<<1) + get_bits1(gb); //part
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    else
    
                        level_code= prefix; //part
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                }else if(prefix==14){
                    if(suffix_length)
    
                        level_code= (prefix<<1) + get_bits1(gb); //part
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    else
                        level_code= prefix + get_bits(gb, 4); //part
                }else{
    
                    level_code= 30 + get_bits(gb, prefix-3); //part
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    if(prefix>=16)
                        level_code += (1<<(prefix-3))-4096;
                }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                if(trailing_ones < 3) level_code += 2;
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                suffix_length = 2;
                mask= -(level_code&1);
                level[trailing_ones]= (((2+level_code)>>1) ^ mask) - mask;
    
            }else{
                if(trailing_ones < 3) level_code += (level_code>>31)|1;
    
                suffix_length = 1;
                if(level_code + 3U > 6U)
                    suffix_length++;
                level[trailing_ones]= level_code;
            }
    
    
            //remaining coefficients have suffix_length > 0
    
            for(i=trailing_ones+1;i<total_coeff;i++) {
    
                static const unsigned int suffix_limit[7] = {0,3,6,12,24,48,INT_MAX };
                int bitsi= show_bits(gb, LEVEL_TAB_BITS);
                level_code= cavlc_level_tab[suffix_length][bitsi][0];
    
                skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]);
                if(level_code >= 100){
                    prefix= level_code - 100;
                    if(prefix == LEVEL_TAB_BITS){
                        prefix += get_level_prefix(gb);
                    }
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
                    if(prefix<15){
                        level_code = (prefix<<suffix_length) + get_bits(gb, suffix_length);
                    }else{
                        level_code = (15<<suffix_length) + get_bits(gb, prefix-3);
                        if(prefix>=16)
                            level_code += (1<<(prefix-3))-4096;
                    }
                    mask= -(level_code&1);
    
                    level_code= (((2+level_code)>>1) ^ mask) - mask;
                }
                level[i]= level_code;
    
                if(suffix_limit[suffix_length] + level_code > 2U*suffix_limit[suffix_length])
    
        }
    
        if(total_coeff == max_coeff)
            zeros_left=0;
        else{
            if(n == CHROMA_DC_BLOCK_INDEX)
                zeros_left= get_vlc2(gb, chroma_dc_total_zeros_vlc[ total_coeff-1 ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
            else