Beispiel #1
0
 public int decode_cabac_p_mb_sub_type(H264Context h)
 {
     if (this.get_cabac(h.cabac_state, 21) != 0)
         return 0;   /* 8x8 */
     if (this.get_cabac(h.cabac_state, 22) == 0)
         return 1;   /* 8x4 */
     if (this.get_cabac(h.cabac_state, 23) != 0)
         return 2;   /* 4x8 */
     return 3;       /* 4x4 */
 }
Beispiel #2
0
        /**
         * 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
         */
        public static int decode_residual(H264Context h, GetBitContext gb, short[] block_base, int block_offset
            , int n, byte[] scantable_base, int scantable_offset, long[] qmul_base, int qmul_offset, int max_coeff)
        {
            //			, int n, uint8_t *scantable, uint32_t *qmul, int max_coeff){
            //MpegEncContext s = h.s;
            int[/*17*/] coeff_token_table_index = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
            int[] level = new int[16];
            int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;

            //FIXME put trailing_onex into the context

            if (n >= H264Context.CHROMA_DC_BLOCK_INDEX)
            {
                coeff_token = gb.get_vlc2(
                        chroma_dc_coeff_token_vlc.table_base, chroma_dc_coeff_token_vlc.table_offset,
                        H264Context.CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1, "coeff_token_CROMA_DC");
                total_coeff = coeff_token >> 2;
                //Console.WriteLine("get_vlc2(CHROMA_DC_COEFF_TOKEN) => total_coeff = " + total_coeff );
            }
            else
            {
                if (n == H264Context.LUMA_DC_BLOCK_INDEX)
                {
                    total_coeff = pred_non_zero_count(h, 0);
                    //Console.WriteLine("Prediected Non-Zero count = "+total_coeff);
                    coeff_token = gb.get_vlc2(
                            coeff_token_vlc[coeff_token_table_index[total_coeff]].table_base,
                            coeff_token_vlc[coeff_token_table_index[total_coeff]].table_offset,
                            H264Context.COEFF_TOKEN_VLC_BITS, 2, "coeff_token_LUMA_DC");
                    total_coeff = coeff_token >> 2;
                    //Console.WriteLine("get_vlc2(LUMA_DC_COEFF_TOKEN) => total_coeff = " + total_coeff );
                }
                else
                {
                    total_coeff = pred_non_zero_count(h, n);

                    // DebugTool.printDebugString("predicted non_zero_count("+n+") = "+total_coeff+"\n");

                    coeff_token = gb.get_vlc2(
                            coeff_token_vlc[coeff_token_table_index[total_coeff]].table_base,
                            coeff_token_vlc[coeff_token_table_index[total_coeff]].table_offset,
                            H264Context.COEFF_TOKEN_VLC_BITS, 2, "coeff_token_LUMA(2)_DC");
                    total_coeff = coeff_token >> 2;

                    // DebugTool.printDebugString("predicted non_zero_count-2 = "+total_coeff+"\n");

                }
            }
            h.non_zero_count_cache[H264Context.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);
                // DebugTool.printDebugString("  --------  Error type 1.0\n");
                return -1;
            }

            trailing_ones = coeff_token & 3;
            //	    tprintf(h.s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
            //assert(total_coeff<=16);

            // DebugTool.printDebugString("   - trailing_ones = "+trailing_ones+"\n");

            i = (int)gb.show_bits(3);
            gb.skip_bits(trailing_ones);
            level[0] = 1 - ((i & 4) >> 1);
            level[1] = 1 - ((i & 2));
            level[2] = 1 - ((i & 1) << 1);

            // DebugTool.printDebugString("   - i = "+i+"\n");

            if (trailing_ones < total_coeff)
            {
                int mask, prefix;
                int suffix_length = ((total_coeff > 10) ? 1 : 0) & ((trailing_ones < 3) ? 1 : 0);
                int bitsi = (int)gb.show_bits(LEVEL_TAB_BITS);
                int level_code = cavlc_level_tab[suffix_length][bitsi][0];

                // DebugTool.printDebugString("   - bitsi = "+bitsi+", level_code = "+level_code+", skip_bit = "+cavlc_level_tab[suffix_length][bitsi][1]+"\n");

                gb.skip_bits(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);

                    // DebugTool.printDebugString("   - prefix = "+prefix+"\n");

                    //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 != 0)
                            level_code = (int)((prefix << 1) + gb.get_bits1("level_code")); //part
                        else
                            level_code = prefix; //part
                    }
                    else if (prefix == 14)
                    {
                        if (suffix_length != 0)
                            level_code = (int)((prefix << 1) + gb.get_bits1("level_code")); //part
                        else
                            level_code = (int)(prefix + gb.get_bits(4, "level_code")); //part
                    }
                    else
                    {
                        // Nok: Prevent bug?? in ffmpeg that the decoder may overflow?
                        level_code = 30 + (int)(gb.get_bits(prefix - 3, "level_code")); //part
                        if (prefix >= 16)
                        {
                            if (prefix > 25 + 3)
                            {
                                // DebugTool.printDebugString("  --------  Error type 1.1\n");
                                //av_log(h.s.avctx, AV_LOG_ERROR, "Invalid level prefix\n");
                                return -1;
                            }
                            level_code += (1 << (prefix - 3)) - 4096;
                        }
                    }

                    if (trailing_ones < 3) level_code += 2;

                    // DebugTool.printDebugString("   - level_code(1) = "+level_code+"\n");

                    suffix_length = 2;
                    mask = -(level_code & 1);
                    level[trailing_ones] = (((2 + level_code) >> 1) ^ mask) - mask;
                }
                else
                {
                    level_code += ((level_code >> 31) | 1) & -((trailing_ones < 3) ? 1 : 0);

                    // DebugTool.printDebugString("   - level_code(2) = "+level_code+"\n");

                    // Fix: for difference between JAVA and C, we need to convert signed to unsigned when we compare
                    //      signed and unsigned number because, in C, such comparing will be done in common part.
                    //      In which, common part in C in unsigned, while java is signed. -= Nok =-
                    suffix_length = 1 + (((0xffffffffL & (level_code + 3)) > 6) ? 1 : 0);
                    level[trailing_ones] = level_code;
                }

                // DebugTool.printDebugString("   - suffix_length(1) = "+suffix_length+"\n");

                //remaining coefficients have suffix_length > 0
                for (i = trailing_ones + 1; i < total_coeff; i++)
                {
                    int[/*7*/] suffix_limit = { 0, 3, 6, 12, 24, 48, int.MaxValue };
                    bitsi = (int)gb.show_bits(LEVEL_TAB_BITS);
                    level_code = cavlc_level_tab[suffix_length][bitsi][0];

                    // DebugTool.printDebugString("       - cavlc_level_tab["+suffix_length+"]["+bitsi+"][0] = "+level_code+"\n");

                    gb.skip_bits(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);
                        }
                        if (prefix < 15)
                        {
                            level_code = (int)((prefix << suffix_length) + gb.get_bits(suffix_length, "level_code"));
                        }
                        else
                        {
                            level_code = (int)((15 << suffix_length) + gb.get_bits(prefix - 3, "level_code"));
                            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;

                    // DebugTool.printDebugString("       - prefix(6) = "+level_code+"\n");

                    // Fix: for difference between JAVA and C, we need to convert signed to unsigned when we compare
                    //      signed and unsigned number because, in C, such comparing will be done in common part.
                    //      In which, common part in C in unsigned, while java is signed. -= Nok =-
                    suffix_length += (((0xffffffffL & (suffix_limit[suffix_length] + level_code)) > (2L * suffix_limit[suffix_length])) ? 1 : 0);
                }

                // DebugTool.printDebugString("   - suffix_length(2) = "+suffix_length+"\n");
            }

            if (total_coeff == max_coeff)
                zeros_left = 0;
            else
            {
                if (n >= H264Context.CHROMA_DC_BLOCK_INDEX)
                {
                    zeros_left = gb.get_vlc2(chroma_dc_total_zeros_vlc[total_coeff - 1].table_base,
                            chroma_dc_total_zeros_vlc[total_coeff - 1].table_offset,
                            H264Context.CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1, "coeff_token_CROMA_DC_TOTAL_ZERO");
                    // DebugTool.printDebugString("get_vlc2(CHROMA_DC_ZERO_LEFT) => zeros_left = " + zeros_left +"\n");
                }
                else
                {
                    zeros_left = gb.get_vlc2(total_zeros_vlc[total_coeff - 1].table_base,
                            total_zeros_vlc[total_coeff - 1].table_offset,
                            H264Context.TOTAL_ZEROS_VLC_BITS, 1, "coeff_token_TOTAL_ZEROS");
                    // DebugTool.printDebugString("get_vlc2(LUMA_DC_ZERO_LEFT) => zeros_left = " + zeros_left +"\n");
                } // if
            }

            /*
            // DebugTool.printDebugString("scantable_offset(before) = {"
                    +scantable_base[scantable_offset+0]+","
                    +scantable_base[scantable_offset+1]+","
                    +scantable_base[scantable_offset+2]+","
                    +scantable_base[scantable_offset+3]+","
                    +scantable_base[scantable_offset+4]
                    +"}\n");
            */
            scantable_offset += zeros_left + total_coeff - 1;

            /*
            // DebugTool.printDebugString("scantable_offset(after) = {"
                    +scantable_base[scantable_offset+0]+","
                    +scantable_base[scantable_offset+1]+","
                    +scantable_base[scantable_offset+2]+","
                    +scantable_base[scantable_offset+3]+","
                    +scantable_base[scantable_offset+4]
                    +"}\n");
             */

            //!!????????????????????????????????? Magic about array resizing??
            if (scantable_offset < 0)
            {
                byte[] new_scantable_base = new byte[scantable_base.Length + (-scantable_offset)];
                Array.Copy(scantable_base, 0, new_scantable_base, -scantable_offset, scantable_base.Length);
                scantable_base = new_scantable_base;
                scantable_offset = 0;
            }

            if (n >= H264Context.LUMA_DC_BLOCK_INDEX)
            {
                // DebugTool.printDebugString("****RESE-CASE 1\n");

                block_base[block_offset + scantable_base[scantable_offset]] = (short)level[0];
                for (i = 1; i < total_coeff && zeros_left > 0; i++)
                {
                    if (zeros_left < 7)
                    {
                        //????????????????????????????????????????/
                        // run_before= gb.get_vlc2((run_vlc-1)[zeros_left].table, H264Context.RUN_VLC_BITS, 1);
                        run_before = gb.get_vlc2(run_vlc[zeros_left - 1].table_base, run_vlc[zeros_left - 1].table_offset, H264Context.RUN_VLC_BITS, 1, "RUN_VLC");
                        //Console.WriteLine("get_vlc2(LUMA_RUN_VLC) => run_before = " + run_before );
                    }
                    else
                    {
                        run_before = gb.get_vlc2(run7_vlc.table_base, run7_vlc.table_offset, H264Context.RUN7_VLC_BITS, 2, "RUN7_VLC");
                        //Console.WriteLine("get_vlc2(LUMA_RUN_VLC7) => run_before = " + run_before );
                    } // if
                    ////Console.WriteLine("run_before = "+run_before);
                    zeros_left -= run_before;
                    scantable_offset -= 1 + run_before;
                    block_base[block_offset + scantable_base[scantable_offset]] = (short)level[i];
                }
                for (; i < total_coeff; i++)
                {
                    scantable_offset--;
                    block_base[block_offset + scantable_base[scantable_offset]] = (short)level[i];
                }
            }
            else
            {
                // DebugTool.printDebugString("****RESE-CASE 2\n");

                block_base[block_offset + scantable_base[scantable_offset]] = (short)((level[0] * qmul_base[qmul_offset + scantable_base[scantable_offset]] + 32) >> 6);
                for (i = 1; i < total_coeff && zeros_left > 0; i++)
                {
                    if (zeros_left < 7)
                    {
                        run_before = gb.get_vlc2(run_vlc[zeros_left - 1].table_base, run_vlc[zeros_left - 1].table_offset, H264Context.RUN_VLC_BITS, 1, "RUN_VLC");
                        //Console.WriteLine("get_vlc2(CHROMA_RUN_VLC) => run_before = " + run_before );
                    }
                    else
                    {
                        run_before = gb.get_vlc2(run7_vlc.table_base, run7_vlc.table_offset, H264Context.RUN7_VLC_BITS, 2, "RUN7_VLC");
                        //Console.WriteLine("get_vlc2(CHROMA_RUN_VLC7) => run_before = " + run_before );
                    } // if
                    ////Console.WriteLine("run_before = "+run_before);
                    zeros_left -= run_before;
                    scantable_offset -= (1 + run_before);
                    block_base[block_offset + scantable_base[scantable_offset]] = (short)((level[i] * qmul_base[qmul_offset + scantable_base[scantable_offset]] + 32) >> 6);
                }
                for (; i < total_coeff; i++)
                {
                    scantable_offset--;
                    block_base[block_offset + scantable_base[scantable_offset]] = (short)((level[i] * qmul_base[qmul_offset + scantable_base[scantable_offset]] + 32) >> 6);
                }
            }

            if (zeros_left < 0)
            {
                //av_log(h.s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s.mb_x, s.mb_y);
                // DebugTool.printDebugString("  --------  Error type 1.2\n");
                return -1;
            }

            return 0;
        }
Beispiel #3
0
        public int decode_cabac_mb_ref(H264Context h, int list, int n)
        {
            int refa = h.ref_cache[list][H264Context.scan8[n] - 1];
            int refb = h.ref_cache[list][H264Context.scan8[n] - 8];
            int @ref = 0;
            int ctx = 0;

            if (h.slice_type_nos == H264Context.FF_B_TYPE)
            {
                if (refa > 0 && 0 == (h.direct_cache[H264Context.scan8[n] - 1] & (H264Context.MB_TYPE_DIRECT2 >> 1)))
                    ctx++;
                if (refb > 0 && 0 == (h.direct_cache[H264Context.scan8[n] - 8] & (H264Context.MB_TYPE_DIRECT2 >> 1)))
                    ctx += 2;
            }
            else
            {
                if (refa > 0)
                    ctx++;
                if (refb > 0)
                    ctx += 2;
            }

            while (this.get_cabac(h.cabac_state, 54 + ctx) != 0)
            {
                @ref++;
                ctx = (ctx >> 2) + 4;
                if (@ref >= 32 /*this.ref_list[list]*/)
                {
                    return -1;
                }
            }
            return @ref;
        }
Beispiel #4
0
        public int decode_cabac_mb_skip(H264Context h, int mb_x, int mb_y)
        {
            int mba_xy, mbb_xy;
            int ctx = 0;

            if (h.mb_aff_frame != 0)
            { //FIXME merge with the stuff in fill_caches?
                int mb_xy = mb_x + (mb_y & ~1) * h.s.mb_stride;
                mba_xy = mb_xy - 1;
                if ((mb_y & 1) != 0
                    && h.slice_table_base[h.slice_table_offset + mba_xy] == h.slice_num
                    && h.mb_field_decoding_flag == ((h.s.current_picture.mb_type_base[h.s.current_picture.mb_type_offset + mba_xy] & H264Context.MB_TYPE_INTERLACED) != 0 ? 1 : 0))
                    mba_xy += h.s.mb_stride;
                if (h.mb_field_decoding_flag != 0)
                {
                    mbb_xy = mb_xy - h.s.mb_stride;
                    if (0 == (mb_y & 1)
                        && h.slice_table_base[h.slice_table_offset + mbb_xy] == h.slice_num
                        && (h.s.current_picture.mb_type_base[h.s.current_picture.mb_type_offset + mbb_xy] & H264Context.MB_TYPE_INTERLACED) != 0)
                        mbb_xy -= h.s.mb_stride;
                }
                else
                    mbb_xy = mb_x + (mb_y - 1) * h.s.mb_stride;
            }
            else
            {
                int mb_xy = h.mb_xy;
                mba_xy = mb_xy - 1;
                mbb_xy = mb_xy - (h.s.mb_stride << 0);
            }

            if (h.slice_table_base[h.slice_table_offset + mba_xy] == h.slice_num && ((h.s.current_picture.mb_type_base[h.s.current_picture.mb_type_offset + mba_xy] & H264Context.MB_TYPE_SKIP) == 0))
                ctx++;
            if (h.slice_table_base[h.slice_table_offset + mbb_xy] == h.slice_num && ((h.s.current_picture.mb_type_base[h.s.current_picture.mb_type_offset + mbb_xy] & H264Context.MB_TYPE_SKIP) == 0))
                ctx++;

            if (h.slice_type_nos == H264Context.FF_B_TYPE)
                ctx += 13;
            int ret = this.get_cabac_noinline(h.cabac_state, 11 + ctx);

            // DebugTool.printDebugString(" * decode_cabac_mb_skip return "+ret+"\n");
            return ret;
        }
Beispiel #5
0
        /**
         * Replicate H264 "master" context to thread contexts.
         */
        public static void clone_slice(H264Context dst, H264Context src)
        {
            //memcpy(dst.block_offset,     src.block_offset, sizeof(dst.block_offset));
            Array.Copy(src.block_offset, 0, dst.block_offset, 0, dst.block_offset.Length);

            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));
            for (int i = 0; i < src.short_ref.Length; i++)
                src.short_ref[i].copyTo(dst.short_ref[i]);

            for (int i = 0; i < src.long_ref.Length; i++)
                src.long_ref[i].copyTo(dst.long_ref[i]);

            //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));
            for (int i = 0; i < src.default_ref_list.Length; i++)
                for (int j = 0; j < src.default_ref_list[i].Length; j++)
                    src.default_ref_list[i][j].copyTo(dst.default_ref_list[i][j]);

            for (int i = 0; i < src.ref_list.Length; i++)
                for (int j = 0; j < src.ref_list[i].Length; j++)
                    src.ref_list[i][j].copyTo(dst.ref_list[i][j]);

            //memcpy(dst.dequant4_coeff,   src.dequant4_coeff,   sizeof(src.dequant4_coeff));
            //memcpy(dst.dequant8_coeff,   src.dequant8_coeff,   sizeof(src.dequant8_coeff));
            for (int i = 0; i < src.dequant4_coeff.Length; i++)
                for (int j = 0; j < src.dequant4_coeff[i].Length; j++)
                    for (int k = 0; k < src.dequant4_coeff[i][j].Length; k++)
                        dst.dequant4_coeff[i][j][k] = src.dequant4_coeff[i][j][k];

            for (int i = 0; i < src.dequant8_coeff.Length; i++)
                for (int j = 0; j < src.dequant8_coeff[i].Length; j++)
                    for (int k = 0; k < src.dequant8_coeff[i][j].Length; k++)
                        dst.dequant8_coeff[i][j][k] = src.dequant8_coeff[i][j][k];
        }
Beispiel #6
0
        public static void dumpDebugFrameData(H264Context h, string msg, bool incrementCounter)
        {
            if (!DEBUG_MODE) return;

            try
            {

                if (incrementCounter)
                    logCount++;

                Console.WriteLine("Dumping Decoder State(" + msg + "): " + logCount + ", Frame: " + h.frame_num);

                // Dump all data inside decoder
                Console.Write("ctx.non_zero_count_cache: ");
                for (int i = 0; i < h.non_zero_count_cache.Length; i++)
                {
                    Console.Write("," + h.non_zero_count_cache[i]);
                } // for
                Console.WriteLine();

                //for(int j=0;j<h.non_zero_count.Length;j++) {
                int j = h.mb_xy;
                if (h.non_zero_count != null)
                    if (j >= 0 && j < h.non_zero_count.Length)
                    {
                        Console.Write("ctx.non_zero_count[" + j + "]: ");
                        for (int i = 0; i < h.non_zero_count[j].Length; i++)
                        {
                            Console.Write("," + h.non_zero_count[j][i]);
                        } // for i
                        Console.WriteLine();
                    } // for j

                // Dump all data inside decoder
                Console.Write("edge_emu_buffer: ");
                for (int i = 0; i < (h.s.width + 64) * 2 * 21 && logCount == 9537; i++)
                {
                    Console.Write("," + h.s.allocated_edge_emu_buffer[h.s.edge_emu_buffer_offset + i]);
                } // for
                Console.WriteLine();

                Console.Write("ctx.mv_cache[0]: ");
                for (int i = 0; i < 40; i++)
                {
                    Console.Write("," + h.mv_cache[0][i][0] + "," + h.mv_cache[0][i][1]);
                } // for
                Console.WriteLine();

                Console.Write("ctx.mv_cache[1]: ");
                for (int i = 0; i < 40; i++)
                {
                    Console.Write("," + h.mv_cache[1][i][0] + "," + h.mv_cache[1][i][1]);
                } // for
                Console.WriteLine();

                Console.Write("ctx.mvd_cache[0]: ");
                for (int i = 0; i < 40; i++)
                {
                    Console.Write("," + h.mvd_cache[0][i][0] + "," + h.mvd_cache[0][i][1]);
                } // for
                Console.WriteLine();

                Console.Write("ctx.mvd_cache[1]: ");
                for (int i = 0; i < 40; i++)
                {
                    Console.Write("," + h.mvd_cache[1][i][0] + "," + h.mvd_cache[1][i][1]);
                } // for
                Console.WriteLine();

                if (h.mvd_table[0] != null)
                {
                    Console.Write("ctx.mvd_table[0]: ");
                    for (int i = 0; i < 40; i++)
                    {
                        Console.Write("," + h.mvd_table[0][i][0] + "," + h.mvd_table[0][i][1]);
                    } // for
                    Console.WriteLine();

                    Console.Write("ctx.mvd_table[1]: ");
                    for (int i = 0; i < 40; i++)
                    {
                        Console.Write("," + h.mvd_table[1][i][0] + "," + h.mvd_table[1][i][1]);
                    } // for
                    Console.WriteLine();
                } // if

                Console.Write("ctx.ref_cache[0]: ");
                for (int i = 0; i < 40; i++)
                {
                    Console.Write("," + h.ref_cache[0][i] + "," + h.ref_cache[0][i]);
                } // for
                Console.WriteLine();

                Console.Write("ctx.ref_cache[1]: ");
                for (int i = 0; i < 40; i++)
                {
                    Console.Write("," + h.ref_cache[1][i] + "," + h.ref_cache[1][i]);
                } // for
                Console.WriteLine();

                Console.Write("error_status_table: ");
                if (h.s.error_status_table != null)
                    for (int i = 0; i </*h.s.error_status_table.Length*/32 && h.s.error_status_table.Length > 32; i++)
                    {
                        Console.Write("," + h.s.error_status_table[i]);
                    } // for
                Console.WriteLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
            } // try
        }
Beispiel #7
0
        public int decode_cabac_mb_cbp_luma(H264Context h)
        {
            int cbp_b, cbp_a, ctx, cbp = 0;

            cbp_a = h.left_cbp;
            cbp_b = h.top_cbp;

            ctx = ((cbp_a & 0x02) == 0 ? 1 : 0) + 2 * ((cbp_b & 0x04) == 0 ? 1 : 0);
            cbp += this.get_cabac_noinline(h.cabac_state, 73 + ctx);
            ctx = ((cbp & 0x01) == 0 ? 1 : 0) + 2 * ((cbp_b & 0x08) == 0 ? 1 : 0);
            cbp += this.get_cabac_noinline(h.cabac_state, 73 + ctx) << 1;
            ctx = ((cbp_a & 0x08) == 0 ? 1 : 0) + 2 * ((cbp & 0x01) == 0 ? 1 : 0);
            cbp += this.get_cabac_noinline(h.cabac_state, 73 + ctx) << 2;
            ctx = ((cbp & 0x04) == 0 ? 1 : 0) + 2 * ((cbp & 0x02) == 0 ? 1 : 0);
            cbp += this.get_cabac_noinline(h.cabac_state, 73 + ctx) << 3;
            return cbp;
        }
Beispiel #8
0
        public int avcodec_open(H264Decoder codec)
        {
            int ret = -1;

            /* If there is a user-supplied mutex locking routine, call it. */
            /*
            if (ff_lockmgr_cb) {
                if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
                    return -1;
            }
            */

            /*
            entangled_thread_counter++;
            if(entangled_thread_counter != 1){
                av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n");
                goto end;
            }
            */

            //if(this.codec!=null || codec == null)
            //    return ret;

            this.priv_data = new H264Context();
            //priv_data.av_opt_set_defaults();

            if (this.coded_width != 0 && this.coded_height != 0)
                this.avcodec_set_dimensions(this.coded_width, this.coded_height);
            else if (this.width != 0 && this.height != 0)
                this.avcodec_set_dimensions(this.width, this.height);

            if ((this.coded_width != 0 || this.coded_height != 0 || this.width != 0 || this.height != 0)
                && (av_image_check_size(this.coded_width, this.coded_height, 0, this) < 0
                   || av_image_check_size(this.width, this.height, 0, this) < 0))
            {
                //av_log(avctx, AV_LOG_WARNING, "ignoring invalid width/height values\n");
                this.avcodec_set_dimensions(0, 0);
            }

            /* if the decoder init function was already called previously,
               free the already allocated subtitle_header before overwriting it */
            //??????????????????????
            //if (codec.decode!=0)
            //   av_freep(&this.subtitle_header);

            //#define SANE_NB_CHANNELS 128U
            //if (this.channels > 128) {
            //    ret = -1;
            //    return ret;
            // }

            this.codec = codec;
            //if ((this.codec_type == AVMEDIA_TYPE_UNKNOWN || this.codec_type == codec.type) &&
            //    this.codec_id == CODEC_ID_NONE) {
            //    this.codec_type = codec.type;
            this.codec_id = codec.id;
            //}
            //if (this.codec_id != codec.id || (this.codec_type != codec.type
            //                       && this.codec_type != AVMEDIA_TYPE_ATTACHMENT)) {
            //av_log(avctx, AV_LOG_ERROR, "codec type or id mismatches\n");
            //    return ret;
            //}
            this.frame_number = 0;
            if (this.codec.max_lowres < this.lowres)
            {
                //av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n",
                //       this.codec.max_lowres);
                return ret;
            }

            ret = this.codec.init(this);
            if (ret < 0)
            {
                return ret;
            } // this
            ret = 0;
            return ret;
        }
Beispiel #9
0
        public int decode_cabac_intra_mb_type(H264Context h, int ctx_base, int intra_slice)
        {
            int state_offset = ctx_base;
            int mb_type;

            if (intra_slice != 0)
            {
                int ctx = 0;
                if ((h.left_type[0] & (H264Context.MB_TYPE_INTRA16x16 | H264Context.MB_TYPE_INTRA_PCM)) != 0)
                    ctx++;
                if ((h.top_type & (H264Context.MB_TYPE_INTRA16x16 | H264Context.MB_TYPE_INTRA_PCM)) != 0)
                    ctx++;
                if (this.get_cabac_noinline(h.cabac_state, state_offset + ctx) == 0)
                    return 0;   /* I4x4 */
                state_offset += 2;
            }
            else
            {
                if (this.get_cabac_noinline(h.cabac_state, state_offset) == 0)
                    return 0;   /* I4x4 */
            }

            if (this.get_cabac_terminate() != 0)
                return 25;  /* PCM */

            mb_type = 1; /* I16x16 */
            mb_type += 12 * this.get_cabac_noinline(h.cabac_state, state_offset + 1); /* cbp_luma != 0 */
            if (this.get_cabac_noinline(h.cabac_state, state_offset + 2) != 0) /* cbp_chroma */
                mb_type += 4 + 4 * this.get_cabac_noinline(h.cabac_state, state_offset + 2 + intra_slice);
            mb_type += 2 * this.get_cabac_noinline(h.cabac_state, state_offset + 3 + intra_slice);
            mb_type += 1 * this.get_cabac_noinline(h.cabac_state, state_offset + 3 + 2 * intra_slice);
            return mb_type;
        }
Beispiel #10
0
        public int decode_cabac_mb_cbp_chroma(H264Context h)
        {
            int ctx;
            int cbp_a, cbp_b;

            cbp_a = (h.left_cbp >> 4) & 0x03;
            cbp_b = (h.top_cbp >> 4) & 0x03;

            ctx = 0;
            if (cbp_a > 0) ctx++;
            if (cbp_b > 0) ctx += 2;
            if (this.get_cabac_noinline(h.cabac_state, 77 + ctx) == 0)
                return 0;

            ctx = 4;
            if (cbp_a == 2) ctx++;
            if (cbp_b == 2) ctx += 2;
            return 1 + this.get_cabac_noinline(h.cabac_state, 77 + ctx);
        }
Beispiel #11
0
        //////////////////////////////////////////////////////
        // H264 Specific CABAC Decoding Functions (2nd level)
        public int decode_cabac_field_decoding_flag(H264Context h)
        {
            int mbb_xy = (int)(h.mb_xy - 2L * h.s.mb_stride);
            int ctx = 0;

            ctx += (h.mb_field_decoding_flag & (/*!!*/h.s.mb_x)); //for FMO:(s.current_picture.mb_type[mba_xy]>>7)&(this.slice_table_base[this.slice_table_offset + mba_xy] == this.slice_num);
            ctx += (int)((h.s.current_picture.mb_type_base[h.s.current_picture.mb_type_offset + mbb_xy] >> 7) & (h.slice_table_base[h.slice_table_offset + mbb_xy] == h.slice_num ? 1 : 0));

            return this.get_cabac_noinline(h.cabac_state, 70 + ctx);// &(this.cabac_state+70)[ctx] );
        }
Beispiel #12
0
 public int decode_cabac_b_mb_sub_type(H264Context h)
 {
     int type;
     if (0 == this.get_cabac(h.cabac_state, 36))
         return 0;   /* B_Direct_8x8 */
     if (0 == this.get_cabac(h.cabac_state, 37))
         return 1 + this.get_cabac(h.cabac_state, 39); /* B_L0_8x8, B_L1_8x8 */
     type = 3;
     if (0 != this.get_cabac(h.cabac_state, 38))
     {
         if (0 != this.get_cabac(h.cabac_state, 39))
             return 11 + this.get_cabac(h.cabac_state, 39); /* B_L1_4x4, B_Bi_4x4 */
         type += 4;
     }
     type += 2 * this.get_cabac(h.cabac_state, 39);
     type += this.get_cabac(h.cabac_state, 39);
     return type;
 }
Beispiel #13
0
        // CABAC Decoder Functions
        public void ff_h264_init_cabac_states(H264Context h)
        {
            var tab =
                (h.slice_type_nos == H264Context.FF_I_TYPE)
                ? cabac_context_init_I
                : cabac_context_init_PB[h.cabac_init_idc]
            ;

            /* calculate pre-state */
            for (int i = 0; i < 460; i++)
            {
                int pre = 2 * (((tab[i][0] * h.s.qscale) >> 4) + tab[i][1]) - 127;
                pre ^= pre >> 31;
                if (pre > 124)
                    pre = 124 + (pre & 1);
                h.cabac_state[i] = pre;
            }
        }
Beispiel #14
0
        /**
         * gets the predicted number of non-zero coefficients.
         * @param n block index
         */
        /*inline*/
        public static int pred_non_zero_count(H264Context h, int n)
        {
            int index8 = H264Context.scan8[n];
            int left = h.non_zero_count_cache[index8 - 1];
            int top = h.non_zero_count_cache[index8 - 8];
            int i = left + top;

            if (i < 64) i = (i + 1) >> 1;

            //tprintf(h.s.avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);

            return i & 31;
        }
Beispiel #15
0
        public int decode_cabac_mb_chroma_pre_mode(H264Context h)
        {
            int mba_xy = h.left_mb_xy[0];
            int mbb_xy = h.top_mb_xy;

            int ctx = 0;

            /* No need to test for IS_INTRA4x4 and IS_INTRA16x16, as we set chroma_pred_mode_table to 0 */
            if (h.left_type[0] != 0 && h.chroma_pred_mode_table[mba_xy] != 0)
                ctx++;

            if (h.top_type != 0 && h.chroma_pred_mode_table[mbb_xy] != 0)
                ctx++;

            if (this.get_cabac_noinline(h.cabac_state, 64 + ctx) == 0)
                return 0;

            if (this.get_cabac_noinline(h.cabac_state, 64 + 3) == 0)
                return 1;
            if (this.get_cabac_noinline(h.cabac_state, 64 + 3) == 0)
                return 2;
            else
                return 3;
        }
Beispiel #16
0
        public int ff_h264_decode_mb_cavlc(H264Context h)
        {
            MpegEncContext s = h.s;
            int mb_xy;
            int partition_count;
            int mb_type, cbp;
            int dct8x8_allowed = h.pps.transform_8x8_mode;

            // DebugTool.dumpDebugFrameData(h, "BEFORE-ff_h264_decode_mb_cavlc");

            mb_xy = h.mb_xy = s.mb_x + s.mb_y * s.mb_stride;

            //tprintf(s.avctx, "pic:%d mb:%d/%d\n", h.frame_num, s.mb_x, s.mb_y);
            cbp = 0; /* avoid warning. FIXME: find a solution without slowing
                        down the code */
            if (h.slice_type_nos != H264Context.FF_I_TYPE)
            {
                if (s.mb_skip_run == -1)
                    s.mb_skip_run = s.gb.get_ue_golomb("mb_skip_run");

                if (0 != s.mb_skip_run--)
                {
                    if (h.mb_aff_frame != 0 && (s.mb_y & 1) == 0)
                    {
                        if (s.mb_skip_run == 0)
                            h.mb_mbaff = h.mb_field_decoding_flag = (int)s.gb.get_bits1("mb_mbaff");
                    }
                    h.decode_mb_skip();
                    return 0;
                }
            }
            if (h.mb_aff_frame != 0)
            {
                if ((s.mb_y & 1) == 0)
                    h.mb_mbaff = h.mb_field_decoding_flag = (int)s.gb.get_bits1("mb_field_decoding_flag");
            }

            h.prev_mb_skipped = 0;

            mb_type = s.gb.get_ue_golomb("mb_type");
            if (h.slice_type_nos == H264Context.FF_B_TYPE)
            {
                if (mb_type < 23)
                {
                    partition_count = H264Data.b_mb_type_info[mb_type].partition_count;
                    mb_type = H264Data.b_mb_type_info[mb_type].type;
                }
                else
                {
                    mb_type -= 23;
                    //	            goto decode_intra_mb;
                    //	        	decode_intra_mb:
                    if (mb_type > 25)
                    {
                        //av_log(h.s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_pict_type_char(h.slice_type), s.mb_x, s.mb_y);
                        return -1;
                    }
                    partition_count = 0;
                    cbp = H264Data.i_mb_type_info[mb_type].cbp;
                    h.intra16x16_pred_mode = H264Data.i_mb_type_info[mb_type].pred_mode;
                    mb_type = H264Data.i_mb_type_info[mb_type].type;
                }
            }
            else if (h.slice_type_nos == H264Context.FF_P_TYPE)
            {
                if (mb_type < 5)
                {
                    partition_count = H264Data.p_mb_type_info[mb_type].partition_count;
                    mb_type = H264Data.p_mb_type_info[mb_type].type;
                }
                else
                {
                    mb_type -= 5;
                    //	            goto decode_intra_mb;
                    //	        	decode_intra_mb:
                    if (mb_type > 25)
                    {
                        //av_log(h.s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_pict_type_char(h.slice_type), s.mb_x, s.mb_y);
                        return -1;
                    }
                    partition_count = 0;
                    cbp = H264Data.i_mb_type_info[mb_type].cbp;
                    h.intra16x16_pred_mode = H264Data.i_mb_type_info[mb_type].pred_mode;
                    mb_type = H264Data.i_mb_type_info[mb_type].type;
                }
            }
            else
            {
                //assert(h.slice_type_nos == H264Context.FF_I_TYPE);
                if (h.slice_type == H264Context.FF_SI_TYPE && mb_type != 0)
                    mb_type--;
                //decode_intra_mb:
                if (mb_type > 25)
                {
                    //av_log(h.s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_pict_type_char(h.slice_type), s.mb_x, s.mb_y);
                    return -1;
                }
                partition_count = 0;
                cbp = H264Data.i_mb_type_info[mb_type].cbp;
                h.intra16x16_pred_mode = H264Data.i_mb_type_info[mb_type].pred_mode;
                mb_type = H264Data.i_mb_type_info[mb_type].type;
            }

            if (h.mb_field_decoding_flag != 0)
                mb_type |= H264Context.MB_TYPE_INTERLACED;

            h.slice_table_base[h.slice_table_offset + mb_xy] = h.slice_num;

            if (0 != (mb_type & H264Context.MB_TYPE_INTRA_PCM))
            {
                int x;

                // We assume these blocks are very rare so we do not optimize it.
                s.gb.align_get_bits();

                // The pixels are stored in the same order as levels in h.mb array.
                for (x = 0; x < ((h.sps.chroma_format_idc != 0) ? 384 : 256); x += 2)
                {
                    // Combine 2 byte to get a short.
                    //((uint8_t*)h.mb)[x]= (int)s.gb.get_bits(8);
                    int val = (int)s.gb.get_bits(8, "val");
                    val = val | (((int)s.gb.get_bits(8, "val")) << 8);
                    h.mb[x / 2] = (short)val;
                }

                // In deblocking, the quantizer is 0
                s.current_picture.qscale_table[mb_xy] = 0;
                // All coeffs are present
                //memset(h.non_zero_count[mb_xy], 16, 32);
                Arrays.Fill(h.non_zero_count[mb_xy], 0, 32, 16);

                s.current_picture.mb_type_base[s.current_picture.mb_type_offset + mb_xy] = mb_type;
                return 0;
            }

            if (h.mb_mbaff != 0)
            {
                h.ref_count[0] <<= 1;
                h.ref_count[1] <<= 1;
            }

            h.fill_decode_neighbors(mb_type);
            h.fill_decode_caches(mb_type);

            //mb_pred
            if (0 != (mb_type & 7))
            {
                int pred_mode;
                //	            init_top_left_availability(h);
                if (0 != (mb_type & H264Context.MB_TYPE_INTRA4x4))
                {
                    int i;
                    int di = 1;
                    if (dct8x8_allowed != 0 && s.gb.get_bits1("MB_TYPE_8x8DCT?") != 0)
                    {
                        mb_type |= H264Context.MB_TYPE_8x8DCT;
                        di = 4;
                    }

                    //	                fill_intra4x4_pred_table(h);
                    for (i = 0; i < 16; i += di)
                    {
                        int mode = h.pred_intra_mode(i);

                        if (0 == s.gb.get_bits1("rem_mode"))
                        {
                            int rem_mode = (int)s.gb.get_bits(3, "rem_mode");
                            mode = rem_mode + ((rem_mode >= mode) ? 1 : 0);
                        }

                        if (di == 4)
                            Rectangle.fill_rectangle_sign(h.intra4x4_pred_mode_cache, H264Context.scan8[i], 2, 2, 8, mode, 1);
                        else
                            h.intra4x4_pred_mode_cache[H264Context.scan8[i]] = mode;
                    }
                    h.ff_h264_write_back_intra_pred_mode();
                    if (h.ff_h264_check_intra4x4_pred_mode() < 0)
                        return -1;
                }
                else
                {
                    h.intra16x16_pred_mode = h.ff_h264_check_intra_pred_mode(h.intra16x16_pred_mode);
                    if (h.intra16x16_pred_mode < 0)
                        return -1;
                }
                if (h.sps.chroma_format_idc != 0)
                {
                    pred_mode = h.ff_h264_check_intra_pred_mode(s.gb.get_ue_golomb_31("pred_mode"));
                    if (pred_mode < 0)
                        return -1;
                    h.chroma_pred_mode = pred_mode;
                }
            }
            else if (partition_count == 4)
            {
                int i, j;
                int[] sub_partition_count = new int[4];
                int list;
                int[][] @ref = Arrays.Create<int>(2, 4);

                if (h.slice_type_nos == H264Context.FF_B_TYPE)
                {
                    for (i = 0; i < 4; i++)
                    {
                        h.sub_mb_type[i] = s.gb.get_ue_golomb_31("sub_mb_type");
                        if (h.sub_mb_type[i] >= 13)
                        {
                            //av_log(h.s.avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h.sub_mb_type[i], s.mb_x, s.mb_y);
                            return -1;
                        }
                        sub_partition_count[i] = H264Data.b_sub_mb_type_info[h.sub_mb_type[i]].partition_count;
                        h.sub_mb_type[i] = H264Data.b_sub_mb_type_info[h.sub_mb_type[i]].type;
                    }
                    if (0 != ((h.sub_mb_type[0] | h.sub_mb_type[1] | h.sub_mb_type[2] | h.sub_mb_type[3]) & H264Context.MB_TYPE_DIRECT2))
                    {
                        mb_type = h.ff_h264_pred_direct_motion(mb_type);
                        h.ref_cache[0][H264Context.scan8[4]] =
                        h.ref_cache[1][H264Context.scan8[4]] =
                        h.ref_cache[0][H264Context.scan8[12]] =
                        h.ref_cache[1][H264Context.scan8[12]] = H264Context.PART_NOT_AVAILABLE;
                    }
                }
                else
                {
                    //assert(h.slice_type_nos == H264Context.FF_P_TYPE); //FIXME SP correct ?
                    for (i = 0; i < 4; i++)
                    {
                        h.sub_mb_type[i] = s.gb.get_ue_golomb_31("sub_mb_type");
                        if (h.sub_mb_type[i] >= 4)
                        {
                            //av_log(h.s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h.sub_mb_type[i], s.mb_x, s.mb_y);
                            return -1;
                        }
                        sub_partition_count[i] = H264Data.p_sub_mb_type_info[h.sub_mb_type[i]].partition_count;
                        h.sub_mb_type[i] = H264Data.p_sub_mb_type_info[h.sub_mb_type[i]].type;
                    }
                }

                for (list = 0; list < h.list_count; list++)
                {
                    int ref_count = ((mb_type & H264Context.MB_TYPE_REF0) != 0) ? 1 : (int)h.ref_count[list];
                    for (i = 0; i < 4; i++)
                    {
                        if (0 != (h.sub_mb_type[i] & H264Context.MB_TYPE_DIRECT2)) continue;
                        if (0 != ((h.sub_mb_type[i]) & (H264Context.MB_TYPE_P0L0 << ((0) + 2 * (list)))))
                        {
                            int tmp;
                            if (ref_count == 1)
                            {
                                tmp = 0;
                            }
                            else if (ref_count == 2)
                            {
                                tmp = (int)s.gb.get_bits1("ref_count?") ^ 1;
                            }
                            else
                            {
                                tmp = s.gb.get_ue_golomb_31("ref_count?");
                                if (tmp >= ref_count)
                                {
                                    //av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
                                    return -1;
                                }
                            }
                            @ref[list][i] = tmp;
                        }
                        else
                        {
                            //FIXME
                            @ref[list][i] = -1;
                        }
                    }
                }

                if (dct8x8_allowed != 0)
                    dct8x8_allowed = h.get_dct8x8_allowed();

                for (list = 0; list < h.list_count; list++)
                {
                    for (i = 0; i < 4; i++)
                    {
                        if (0 != (h.sub_mb_type[i] & H264Context.MB_TYPE_DIRECT2))
                        {
                            h.ref_cache[list][H264Context.scan8[4 * i]] = h.ref_cache[list][H264Context.scan8[4 * i] + 1];
                            continue;
                        }
                        h.ref_cache[list][H264Context.scan8[4 * i]] = h.ref_cache[list][H264Context.scan8[4 * i] + 1] =
                        h.ref_cache[list][H264Context.scan8[4 * i] + 8] = h.ref_cache[list][H264Context.scan8[4 * i] + 9] = @ref[list][i];

                        if (((h.sub_mb_type[i]) & (H264Context.MB_TYPE_P0L0 << ((0) + 2 * (list)))) != 0)
                        {//IS_DIR(h.sub_mb_type[i], 0, list)){
                            int sub_mb_type = h.sub_mb_type[i];
                            int block_width = ((sub_mb_type & (H264Context.MB_TYPE_16x16 | H264Context.MB_TYPE_16x8)) != 0 ? 2 : 1);
                            for (j = 0; j < sub_partition_count[i]; j++)
                            {
                                int mx, my;
                                int index = 4 * i + block_width * j;
                                //int16_t (* mv_cache)[2]= &h.mv_cache[list][ H264Context.scan8[index] ];
                                int[][] mv_cache_base = h.mv_cache[list];
                                int my_cache_offset = H264Context.scan8[index];
                                int[] mxmy = new int[2];
                                h.pred_motion(index, block_width, list, h.ref_cache[list][H264Context.scan8[index]], mxmy);
                                mx = mxmy[0];
                                my = mxmy[1];
                                mx += s.gb.get_se_golomb("mx?");
                                my += s.gb.get_se_golomb("my?");
                                //tprintf(s.avctx, "final mv:%d %d\n", mx, my);

                                if (0 != (sub_mb_type & H264Context.MB_TYPE_16x16))
                                {
                                    mv_cache_base[my_cache_offset + 1][0] =
                                    mv_cache_base[my_cache_offset + 8][0] = mv_cache_base[my_cache_offset + 9][0] = mx;
                                    mv_cache_base[my_cache_offset + 1][1] =
                                    mv_cache_base[my_cache_offset + 8][1] = mv_cache_base[my_cache_offset + 9][1] = my;
                                }
                                else if (0 != (sub_mb_type & H264Context.MB_TYPE_16x8))
                                {
                                    mv_cache_base[my_cache_offset + 1][0] = mx;
                                    mv_cache_base[my_cache_offset + 1][1] = my;
                                }
                                else if (0 != (sub_mb_type & H264Context.MB_TYPE_8x16))
                                {
                                    mv_cache_base[my_cache_offset + 8][0] = mx;
                                    mv_cache_base[my_cache_offset + 8][1] = my;
                                }
                                mv_cache_base[my_cache_offset + 0][0] = mx;
                                mv_cache_base[my_cache_offset + 0][1] = my;
                            }
                        }
                        else
                        {
                            /*
                            uint32_t *p= (uint32_t *)&h.mv_cache[list][ scan8[4*i] ][0];
                            p[0] = p[1]=
                            p[8] = p[9]= 0;
                            */
                            h.mv_cache[list][H264Context.scan8[4 * i] + 0][0] = (short)0;
                            h.mv_cache[list][H264Context.scan8[4 * i] + 1][0] = (short)0;
                            h.mv_cache[list][H264Context.scan8[4 * i] + 8][0] = (short)0;
                            h.mv_cache[list][H264Context.scan8[4 * i] + 9][0] = (short)0;
                            h.mv_cache[list][H264Context.scan8[4 * i] + 0][1] = (short)0;
                            h.mv_cache[list][H264Context.scan8[4 * i] + 1][1] = (short)0;
                            h.mv_cache[list][H264Context.scan8[4 * i] + 8][1] = (short)0;
                            h.mv_cache[list][H264Context.scan8[4 * i] + 9][1] = (short)0;
                        }
                    }
                }
            }
            else if (0 != (mb_type & H264Context.MB_TYPE_DIRECT2))
            {
                mb_type = h.ff_h264_pred_direct_motion(mb_type);
                dct8x8_allowed &= h.sps.direct_8x8_inference_flag;
            }
            else
            {
                int list, mx = 0, my = 0, i;
                //FIXME we should set ref_idx_l? to 0 if we use that later ...
                if (0 != (mb_type & H264Context.MB_TYPE_16x16))
                {
                    for (list = 0; list < h.list_count; list++)
                    {
                        int val;
                        if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((0) + 2 * (list)))) != 0)
                        {
                            if (h.ref_count[list] == 1)
                            {
                                val = 0;
                            }
                            else if (h.ref_count[list] == 2)
                            {
                                val = (int)(s.gb.get_bits1("ref_count?") ^ 1);
                            }
                            else
                            {
                                val = s.gb.get_ue_golomb_31("ref_count?");
                                if (val >= h.ref_count[list])
                                {
                                    //av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                    return -1;
                                }
                            }
                            Rectangle.fill_rectangle_sign(h.ref_cache[list], H264Context.scan8[0], 4, 4, 8, val, 1);
                        }
                    }
                    for (list = 0; list < h.list_count; list++)
                    {
                        if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((0) + 2 * (list)))) != 0)
                        {
                            int[] mxmy = new int[] { mx, my };
                            h.pred_motion(0, 4, list, h.ref_cache[list][H264Context.scan8[0]], mxmy);
                            mx = mxmy[0];
                            my = mxmy[1];
                            mx += s.gb.get_se_golomb("mx?");
                            my += s.gb.get_se_golomb("my?");
                            //int val = h.pack16to32(mx,my);

                            // DebugTool.printDebugString("    ****(1) mx="+mx+", my="+my+", val="+val+"\n");
                            //tprintf(s.avctx, "final mv:%d %d\n", mx, my);

                            Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], H264Context.scan8[0], 4, 4, 8, H264Context.pack16to32(mx, my), 4);
                        }
                    }
                }
                else if (0 != (mb_type & H264Context.MB_TYPE_16x8))
                {
                    for (list = 0; list < h.list_count; list++)
                    {
                        for (i = 0; i < 2; i++)
                        {
                            int val;
                            if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((i) + 2 * (list)))) != 0)
                            {
                                if (h.ref_count[list] == 1)
                                {
                                    val = 0;
                                }
                                else if (h.ref_count[list] == 2)
                                {
                                    val = (int)(s.gb.get_bits1("ref_count?") ^ 1);
                                }
                                else
                                {
                                    val = s.gb.get_ue_golomb_31("ref_count?");
                                    if (val >= h.ref_count[list])
                                    {
                                        //av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                        return -1;
                                    }
                                }
                            }
                            else
                            {
                                //!!?????????????????????? Need unsigneded??
                                val = H264Context.LIST_NOT_USED;
                            } // if
                            Rectangle.fill_rectangle_sign(h.ref_cache[list], H264Context.scan8[0] + 16 * i, 4, 2, 8, val, 1);
                        }
                    }
                    for (list = 0; list < h.list_count; list++)
                    {
                        for (i = 0; i < 2; i++)
                        {
                            int val;
                            if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((i) + 2 * (list)))) != 0)
                            {
                                int[] mxmy = new int[] { mx, my };
                                h.pred_16x8_motion(8 * i, list, h.ref_cache[list][H264Context.scan8[0] + 16 * i], mxmy);
                                mx = mxmy[0];
                                my = mxmy[1];
                                mx += s.gb.get_se_golomb("mx?");
                                my += s.gb.get_se_golomb("my?");
                                //tprintf(s.avctx, "final mv:%d %d\n", mx, my);

                                val = H264Context.pack16to32(mx, my);

                                // DebugTool.printDebugString("    ****(2) mx="+mx+", my="+my+", val="+val+"\n");

                            }
                            else
                                val = 0;
                            Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], H264Context.scan8[0] + 16 * i, 4, 2, 8, val, 4);
                        }
                    }
                }
                else
                {
                    ////assert(IS_8X16(mb_type));
                    for (list = 0; list < h.list_count; list++)
                    {
                        for (i = 0; i < 2; i++)
                        {
                            int val;
                            if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((i) + 2 * (list)))) != 0)
                            { //FIXME optimize
                                if (h.ref_count[list] == 1)
                                {
                                    val = 0;
                                }
                                else if (h.ref_count[list] == 2)
                                {
                                    val = (int)(s.gb.get_bits1("ref-count?") ^ 1);
                                }
                                else
                                {
                                    val = s.gb.get_ue_golomb_31("ref-count?");
                                    if (val >= h.ref_count[list])
                                    {
                                        //av_log(h.s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                        return -1;
                                    }
                                }
                            }
                            else
                            {
                                // !!?????????? Need Unsigned
                                val = H264Context.LIST_NOT_USED;
                            } // if

                            Rectangle.fill_rectangle_sign(h.ref_cache[list], H264Context.scan8[0] + 2 * i, 2, 4, 8, val, 1);
                        }
                    }
                    for (list = 0; list < h.list_count; list++)
                    {
                        for (i = 0; i < 2; i++)
                        {
                            int val;
                            if (((mb_type) & (H264Context.MB_TYPE_P0L0 << ((i) + 2 * (list)))) != 0)
                            {
                                int[] mxmy = new int[] { mx, my };
                                h.pred_8x16_motion(i * 4, list, h.ref_cache[list][H264Context.scan8[0] + 2 * i], mxmy);
                                mx = mxmy[0];
                                my = mxmy[1];
                                mx += s.gb.get_se_golomb("mx?");
                                my += s.gb.get_se_golomb("my?");
                                //tprintf(s.avctx, "final mv:%d %d\n", mx, my);

                                val = H264Context.pack16to32(mx, my);

                                // DebugTool.printDebugString("    ****(3) mx="+mx+", my="+my+", val="+val+"\n");

                            }
                            else
                                val = 0;
                            Rectangle.fill_rectangle_mv_cache(h.mv_cache[list], H264Context.scan8[0] + 2 * i, 2, 4, 8, val, 4);
                        }
                    }
                }
            }

            if (0 != (mb_type & (H264Context.MB_TYPE_16x16 | H264Context.MB_TYPE_16x8 | H264Context.MB_TYPE_8x16 | H264Context.MB_TYPE_8x8)))
                h.write_back_motion(mb_type);

            if (0 == (mb_type & H264Context.MB_TYPE_INTRA16x16))
            {
                cbp = s.gb.get_ue_golomb("cbp");
                if (cbp > 47)
                {
                    //av_log(h.s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s.mb_x, s.mb_y);
                    return -1;
                }

                if (h.sps.chroma_format_idc != 0)
                {
                    if (0 != (mb_type & H264Context.MB_TYPE_INTRA4x4)) cbp = H264Data.golomb_to_intra4x4_cbp[cbp];
                    else cbp = H264Data.golomb_to_inter_cbp[cbp];
                }
                else
                {
                    if (0 != (mb_type & H264Context.MB_TYPE_INTRA4x4)) cbp = golomb_to_intra4x4_cbp_gray[cbp];
                    else cbp = golomb_to_inter_cbp_gray[cbp];
                }
            }

            if (dct8x8_allowed != 0 && (cbp & 15) != 0 && 0 == (mb_type & 7))
            {
                mb_type |= (int)(H264Context.MB_TYPE_8x8DCT * s.gb.get_bits1("mb_type"));
            }
            h.cbp =
            h.cbp_table[mb_xy] = cbp;
            s.current_picture.mb_type_base[s.current_picture.mb_type_offset + mb_xy] = mb_type;

            if (cbp != 0 || 0 != (mb_type & H264Context.MB_TYPE_INTRA16x16))
            {
                int i8x8, i4x4, chroma_idx;
                int dquant;
                GetBitContext gb = (((mb_type & 7) != 0) ? h.intra_gb_ptr : h.inter_gb_ptr);
                //uint8_t *scan, *scan8x8;
                byte[] scan;
                byte[] scan8x8;

                if (0 != (mb_type & H264Context.MB_TYPE_INTERLACED))
                {
                    scan8x8 = (s.qscale != 0 ? h.field_scan8x8_cavlc : h.field_scan8x8_cavlc_q0);
                    scan = (s.qscale != 0 ? h.field_scan : h.field_scan_q0);
                }
                else
                {
                    scan8x8 = (s.qscale != 0 ? h.zigzag_scan8x8_cavlc : h.zigzag_scan8x8_cavlc_q0);
                    scan = (s.qscale != 0 ? h.zigzag_scan : h.zigzag_scan_q0);
                }

                dquant = s.gb.get_se_golomb("dquant");

                s.qscale += dquant;

                if ((/*(unsigned)*/s.qscale) > 51)
                {
                    if (s.qscale < 0) s.qscale += 52;
                    else s.qscale -= 52;
                    if ((/*(unsigned)*/s.qscale) > 51)
                    {
                        //av_log(h.s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s.mb_x, s.mb_y);
                        return -1;
                    }
                }

                h.chroma_qp[0] = h.pps.chroma_qp_table[0][s.qscale];
                h.chroma_qp[1] = h.pps.chroma_qp_table[1][s.qscale];
                if (0 != (mb_type & H264Context.MB_TYPE_INTRA16x16))
                {
                    // Fill 16 uint16_t with 0
                    Arrays.Fill(h.mb_luma_dc, 0, 16, (short)0);
                    //AV_ZERO128(h.mb_luma_dc+0);
                    //AV_ZERO128(h.mb_luma_dc+8);
                    if (decode_residual(h, h.intra_gb_ptr, h.mb_luma_dc, 0, H264Context.LUMA_DC_BLOCK_INDEX, scan, 0, h.dequant4_coeff[0][s.qscale], 0, 16) < 0)
                    {
                        return -1; //FIXME continue if partitioned and other return -1 too
                    }

                    //assert((cbp&15) == 0 || (cbp&15) == 15);

                    if ((cbp & 15) != 0)
                    {
                        /////////////////////////////////

                        for (i8x8 = 0; i8x8 < 4; i8x8++)
                        {
                            for (i4x4 = 0; i4x4 < 4; i4x4++)
                            {
                                int index = i4x4 + 4 * i8x8;
                                if (decode_residual(h, h.intra_gb_ptr, h.mb, 16 * index, index, scan, 1, h.dequant4_coeff[0][s.qscale], 0, 15) < 0)
                                {
                                    return -1;
                                }

                            }
                        }

                    }
                    else
                    {
                        Rectangle.fill_rectangle_unsign(h.non_zero_count_cache, H264Context.scan8[0], 4, 4, 8, 0, 1);
                    }
                }
                else
                {
                    for (i8x8 = 0; i8x8 < 4; i8x8++)
                    {
                        if ((cbp & (1 << i8x8)) != 0)
                        {
                            if (0 != (mb_type & H264Context.MB_TYPE_8x8DCT))
                            {
                                short[] buf_base = h.mb;
                                int buf_offset = 64 * i8x8;
                                for (i4x4 = 0; i4x4 < 4; i4x4++)
                                {
                                    if (decode_residual(h, gb, buf_base, buf_offset, i4x4 + 4 * i8x8, scan8x8, 16 * i4x4,
                                                        h.dequant8_coeff[(0 != (mb_type & 7)) ? 0 : 1][s.qscale], 0, 16) < 0)
                                        return -1;
                                }
                                int[] nnz_base = h.non_zero_count_cache;
                                int nnz_offset = H264Context.scan8[4 * i8x8];
                                nnz_base[nnz_offset + 0] += nnz_base[nnz_offset + 1] + nnz_base[nnz_offset + 8] + nnz_base[nnz_offset + 9];
                            }
                            else
                            {
                                for (i4x4 = 0; i4x4 < 4; i4x4++)
                                {
                                    int index = i4x4 + 4 * i8x8;

                                    if (decode_residual(h, gb, h.mb, 16 * index, index, scan, 0, h.dequant4_coeff[(mb_type & 7) != 0 ? 0 : 3][s.qscale], 0, 16) < 0)
                                    {
                                        return -1;
                                    }
                                }
                            }
                        }
                        else
                        {
                            int[] nnz_base = h.non_zero_count_cache;
                            int nnz_offset = H264Context.scan8[4 * i8x8];
                            nnz_base[nnz_offset + 0] = nnz_base[nnz_offset + 1] = nnz_base[nnz_offset + 8] = nnz_base[nnz_offset + 9] = 0;
                        }
                    }
                }

                if ((cbp & 0x030) != 0)
                {
                    // Fill 2x4 uint_16t with 0
                    Arrays.Fill(h.mb_chroma_dc[0], (short)0);
                    Arrays.Fill(h.mb_chroma_dc[1], (short)0);
                    //AV_ZERO128(h.mb_chroma_dc);
                    for (chroma_idx = 0; chroma_idx < 2; chroma_idx++)
                    {
                        if (decode_residual(h, gb, h.mb_chroma_dc[chroma_idx], 0, H264Context.CHROMA_DC_BLOCK_INDEX + chroma_idx, H264Data.chroma_dc_scan, 0, null, 0, 4) < 0)
                        {

                            // DebugTool.printDebugString("----Error type 16\n");

                            return -1;
                        }
                    }
                }

                if ((cbp & 0x020) != 0)
                {
                    for (chroma_idx = 0; chroma_idx < 2; chroma_idx++)
                    {
                        long[] qmul = h.dequant4_coeff[chroma_idx + 1 + (((mb_type & 7) != 0) ? 0 : 3)][h.chroma_qp[chroma_idx]];
                        for (i4x4 = 0; i4x4 < 4; i4x4++)
                        {
                            int index = 16 + 4 * chroma_idx + i4x4;
                            if (decode_residual(h, gb, h.mb, 16 * index, index, scan, 1, qmul, 0, 15) < 0)
                            {
                                return -1;
                            }
                        }
                    }
                }
                else
                {
                    int[] nnz = h.non_zero_count_cache;
                    nnz[H264Context.scan8[16] + 0] = nnz[H264Context.scan8[16] + 1] = nnz[H264Context.scan8[16] + 8] = nnz[H264Context.scan8[16] + 9] =
                    nnz[H264Context.scan8[20] + 0] = nnz[H264Context.scan8[20] + 1] = nnz[H264Context.scan8[20] + 8] = nnz[H264Context.scan8[20] + 9] = 0;
                }
            }
            else
            {
                int[] nnz = h.non_zero_count_cache;
                Rectangle.fill_rectangle_unsign(nnz, H264Context.scan8[0], 4, 4, 8, 0, 1);
                nnz[H264Context.scan8[16] + 0] = nnz[H264Context.scan8[16] + 1] = nnz[H264Context.scan8[16] + 8] = nnz[H264Context.scan8[16] + 9] =
                nnz[H264Context.scan8[20] + 0] = nnz[H264Context.scan8[20] + 1] = nnz[H264Context.scan8[20] + 8] = nnz[H264Context.scan8[20] + 9] = 0;
            }
            s.current_picture.qscale_table[mb_xy] = s.qscale;
            h.write_back_non_zero_count();

            if (h.mb_mbaff != 0)
            {
                h.ref_count[0] >>= 1;
                h.ref_count[1] >>= 1;
            }

            // DebugTool.dumpDebugFrameData(h, "AFTER-ff_h264_decode_mb_cavlc");

            return 0;
        }
Beispiel #17
0
        public int decode_cabac_mb_intra4x4_pred_mode(H264Context h, int pred_mode)
        {
            int mode = 0;

            if (this.get_cabac(h.cabac_state, 68) != 0)
                return pred_mode;

            mode += 1 * this.get_cabac(h.cabac_state, 69);
            mode += 2 * this.get_cabac(h.cabac_state, 69);
            mode += 4 * this.get_cabac(h.cabac_state, 69);

            return mode + ((mode >= pred_mode) ? 1 : 0);
        }
Beispiel #18
0
 public int avcodec_close()
 {
     if (this.codec != null)
         this.codec.close(this);
     avcodec_default_free_buffers();
     this.coded_frame = null;
     this.priv_data = null;
     this.codec = null;
     return 0;
 }
Beispiel #19
0
        public int decode_cabac_mb_mvd(H264Context h, int ctxbase, int amvd, int[] mvda)
        {
            int mvd;

            // DebugTool.printDebugString(" - decode_cabac_mb_mvd: ctxbase="+ctxbase+", amvd="+amvd+", state_offset="+(ctxbase+((amvd-3)>>(INT_BIT-1))+((amvd-33)>>(INT_BIT-1))+2)+"\n");

            // DebugTool.printDebugString(" - INT_BIT="+INT_BIT+", ((amvd-3)>>(INT_BIT-1))="+((amvd-3)>>(INT_BIT-1))+", ((amvd-33)>>(INT_BIT-1))="+((amvd-33)>>(INT_BIT-1))+"\n");

            if (0 == this.get_cabac(h.cabac_state, ctxbase + ((amvd - 3) >> (INT_BIT - 1)) + ((amvd - 33) >> (INT_BIT - 1)) + 2))
            {
                mvda[0] = 0;
                return 0;
            }

            mvd = 1;
            ctxbase += 3;
            while (mvd < 9 && this.get_cabac(h.cabac_state, ctxbase) != 0)
            {
                if (mvd < 4)
                    ctxbase++;
                mvd++;
            }

            if (mvd >= 9)
            {
                int k = 3;
                while (this.get_cabac_bypass() != 0)
                {
                    mvd += 1 << k;
                    k++;
                    if (k > 24)
                    {
                        //Console.WriteLine("overflow in decode_cabac_mb_mvd");
                        return int.MinValue;
                    }
                }
                while (k-- != 0)
                {
                    mvd += this.get_cabac_bypass() << k;
                }
                mvda[0] = mvd < 70 ? mvd : 70;
            }
            else
                mvda[0] = mvd;
            return this.get_cabac_bypass_sign(-mvd);
        }
Beispiel #20
0
        /**
         * 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
         */
        public static int decode_slice_header(H264Context h, H264Context h0)
        {
            MpegEncContext s = h.s;
            MpegEncContext s0 = h0.s;
            /*unsigned */
            int first_mb_in_slice;
            /*unsigned */
            int pps_id;
            int num_ref_idx_active_override_flag;
            /*unsigned */
            int slice_type, tmp, i, j;
            int default_ref_list_done = 0;
            int last_pic_structure;

            s.dropable = (h.nal_ref_idc == 0) ? 1 : 0;

            s.me.qpel_put = DSPContext.put_h264_qpel_pixels_tab;
            s.me.qpel_avg = DSPContext.avg_h264_qpel_pixels_tab;

            first_mb_in_slice = s.gb.get_ue_golomb("first_mb_in_slice");

            if (first_mb_in_slice == 0)
            { //FIXME better field boundary detection
                if ((h0.current_slice != 0) && (s.picture_structure != Constants.PICT_FRAME))
                {
                    h.field_end();
                } // if

                h0.current_slice = 0;
                if (0 == s0.first_field)
                    s.current_picture_ptr = null;
            }

            slice_type = s.gb.get_ue_golomb_31("slice_type");
            if (slice_type > 9)
            {
                // DebugTool.printDebugString("   --- decode_slide_header error case 0\n");
                //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);
                return -60;
            }
            if (slice_type > 4)
            {
                slice_type -= 5;
                h.slice_type_fixed = 1;
            }
            else
                h.slice_type_fixed = 0;

            slice_type = H264Data.golomb_to_pict_type[slice_type];

            /*
            if(slice_type == H264Context.FF_I_TYPE) {
                //Console.WriteLine("Decoding I-Slice.");
            } else if(slice_type == H264Context.FF_P_TYPE) {
                //Console.WriteLine("Decoding P-Slice.");
            } else if(slice_type == H264Context.FF_B_TYPE) {
                //Console.WriteLine("Decoding B-Slice.");
            } else if(slice_type == H264Context.FF_S_TYPE) {
                //Console.WriteLine("Decoding S-Slice.");
            } else if(slice_type == H264Context.FF_SI_TYPE) {
                //Console.WriteLine("Decoding SI-Slice.");
            } else if(slice_type == H264Context.FF_SP_TYPE) {
                //Console.WriteLine("Decoding SP-Slice.");
            } else if(slice_type == H264Context.FF_BI_TYPE) {
                //Console.WriteLine("Decoding BI-Slice.");
            } // if
            */

            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

            pps_id = s.gb.get_ue_golomb("pps_id");
            if (pps_id >= MAX_PPS_COUNT)
            {
                //av_log(h.s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
                // DebugTool.printDebugString("   --- decode_slide_header error case 1\n");
                return -61;
            }
            if (null == h0.pps_buffers[pps_id])
            {
                //av_log(h.s.avctx, AV_LOG_ERROR, "non-existing PPS %u referenced\n", pps_id);
                // DebugTool.printDebugString("   --- decode_slide_header error case 2\n");
                return -62;
            }
            h0.pps_buffers[pps_id].copyTo(h.pps);

            if (null == h0.sps_buffers[(int)h.pps.sps_id])
            {
                //av_log(h.s.avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h.pps.sps_id);
                // DebugTool.printDebugString("   --- decode_slide_header error case 3\n");
                return -63;
            }
            h0.sps_buffers[(int)h.pps.sps_id].copyTo(h.sps);

            s.profile = h.sps.profile_idc;
            s.level = h.sps.level_idc;
            s.refs = h.sps.ref_frame_count;

            if (h == h0 && h.dequant_coeff_pps != pps_id)
            {
                h.dequant_coeff_pps = pps_id;
                h.init_dequant_tables();
            }

            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;

            s.width = (int)(16 * s.mb_width - 2 * Math.Min(h.sps.crop_right, 7));
            if (h.sps.frame_mbs_only_flag != 0)
                s.height = (int)(16 * s.mb_height - 2 * Math.Min(h.sps.crop_bottom, 7));
            else
                s.height = (int)(16 * s.mb_height - 4 * Math.Min(h.sps.crop_bottom, 7));

            if (s.context_initialized != 0
                && (   /*s.width != s.avctx.width || s.height != s.avctx.height
                    ||*/ av_cmp_q(h.sps.sar, s.sample_aspect_ratio) != 0))
            {
                if (h != h0)
                {
                    // DebugTool.printDebugString("   --- decode_slide_header error case 4\n");
                    return -64;   // width / height changed during parallelized decoding
                }
                h.free_tables();
                s.flush_dpb();
                s.MPV_common_end();
            }

            if (0 == s.context_initialized)
            {
                if (h != h0)
                {
                    // DebugTool.printDebugString("   --- decode_slide_header error case 5\n");
                    return -65;  // we cant (re-)initialize context during parallel decoding
                }

                s.avcodec_set_dimensions(s.width, s.height);
                s.sample_aspect_ratio = h.sps.sar;
                //av_assert0(s.avctx.sample_aspect_ratio.den);

                if (0 != h.sps.video_signal_type_present_flag)
                {
                    s.color_range = ((h.sps.full_range != 0) ? MpegEncContext.AVCOL_RANGE_JPEG : MpegEncContext.AVCOL_RANGE_MPEG);
                    if (h.sps.colour_description_present_flag != 0)
                    {
                        s.color_primaries = h.sps.color_primaries;
                        s.color_trc = h.sps.color_trc;
                        s.colorspace = h.sps.colorspace;
                    }
                }

                if (h.sps.timing_info_present_flag != 0)
                {
                    long den = h.sps.time_scale;
                    if (h.x264_build < 44)
                        den *= 2;
                    int[] param = new int[] { s.time_base.num, s.time_base.den, };
                    av_reduce(param,
                              h.sps.num_units_in_tick, den, 1 << 30);
                    s.time_base.num = param[0];
                    s.time_base.den = param[1];
                }
                s.pix_fmt = MpegEncContext.get_format(
                                                         s.codec.pix_fmts != null ?
                                                         s.codec.pix_fmts :
                                                         s.color_range == MpegEncContext.AVCOL_RANGE_JPEG ?
                                                         hwaccel_pixfmt_list_h264_jpeg_420 :
                                                         MpegEncContext.ff_hwaccel_pixfmt_list_420);
                s.hwaccel = 0; // No H/W Accel!! // ff_find_hwaccel(s.avctx.codec.id, s.avctx.pix_fmt);

                if (s.MPV_common_init() < 0)
                {
                    // DebugTool.printDebugString("   --- decode_slide_header error case 6\n");
                    return -66;
                }
                s.first_field = 0;
                h.prev_interlaced_frame = 1;

                h.init_scan_tables();
                h.ff_h264_alloc_tables();

                /*// We use single thread decoder
                for(i = 1; i < 1; i++) {
                    H264Context c;
                    c = h.thread_context[i] = new H264Context();
                    memcpy(c, h.s.thread_context[i], sizeof(MpegEncContext));
                    memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));
                    c.h264dsp = h.h264dsp;
                    c.sps = h.sps;
                    c.pps = h.pps;
                    c.init_scan_tables();
                    clone_tables(c, h, i);
                }
                */
                for (i = 0; i < s.thread_count; i++)
                    if (h.thread_context[i].context_init() < 0)
                    {
                        // DebugTool.printDebugString("   --- decode_slide_header error case 7\n");
                        return -67;
                    }
            }

            h.frame_num = (int)s.gb.get_bits(h.sps.log2_max_frame_num, "frame_num");

            h.mb_mbaff = 0;
            h.mb_aff_frame = 0;
            last_pic_structure = s0.picture_structure;
            if (h.sps.frame_mbs_only_flag != 0)
            {
                s.picture_structure = Constants.PICT_FRAME;
            }
            else
            {
                if (s.gb.get_bits1("field_pic_flag") != 0)
                { //field_pic_flag
                    s.picture_structure = (int)(Constants.PICT_TOP_FIELD + s.gb.get_bits1("bottom_field_flag")); //bottom_field_flag
                }
                else
                {
                    s.picture_structure = Constants.PICT_FRAME;
                    h.mb_aff_frame = h.sps.mb_aff;
                }
            }
            h.mb_field_decoding_flag = ((s.picture_structure) != Constants.PICT_FRAME ? 1 : 0);

            if (h0.current_slice == 0)
            {
                while (h.frame_num != h.prev_frame_num &&
                      h.frame_num != ((h.prev_frame_num + 1) % (1 << h.sps.log2_max_frame_num)))
                {
                    AVFrame prev = ((h.short_ref_count != 0) ? h.short_ref[0] : null);
                    //av_log(h.s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", h.frame_num, h.prev_frame_num);
                    if (h.ff_h264_frame_start() < 0)
                    {
                        // DebugTool.printDebugString("   --- decode_slide_header error case 8\n");
                        return -68;
                    }
                    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;
                    h.ff_generate_sliding_window_mmcos();
                    h.ff_h264_execute_ref_pic_marking(h.mmco, h.mmco_index);
                    /* Error concealment: if a ref is missing, copy the previous ref in its place.
                     * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions
                     * about there being no actual duplicates.
                     * FIXME: this doesn't copy padding for out-of-frame motion vectors.  Given we're
                     * concealing a lost frame, this probably isn't noticable by comparison, but it should
                     * be fixed. */
                    if (h.short_ref_count != 0)
                    {
                        if (prev != null)
                        {
                            ImageUtils.av_image_copy(h.short_ref[0].data_base,
                                    h.short_ref[0].data_offset,
                                    h.short_ref[0].linesize,
                                /*( uint8_t**)*/prev.data_base, prev.data_offset, prev.linesize,
                                          s.pix_fmt, s.mb_width * 16, s.mb_height * 16);
                            h.short_ref[0].poc = prev.poc + 2;
                        }
                        h.short_ref[0].frame_num = h.prev_frame_num;
                    }
                }

                /* See if we have a decoded first field looking for a pair... */
                if (s0.first_field != 0)
                {
                    ////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 (!(s.picture_structure != Constants.PICT_FRAME) || 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 = ((s.picture_structure != Constants.PICT_FRAME) ? 1 : 0);

                    }
                    else
                    {
                        if (h.nal_ref_idc != 0 &&
                                s0.current_picture_ptr.reference != 0 &&
                                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 = ((s.picture_structure != Constants.PICT_FRAME) ? 1 : 0);
                }

                if ((0 == ((s.picture_structure != Constants.PICT_FRAME) ? 1 : 0) || 0 != s0.first_field) && h.ff_h264_frame_start() < 0)
                {
                    s0.first_field = 0;
                    // DebugTool.printDebugString("   --- decode_slide_header error case 9\n");

                    return -69;
                }
            }
            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 << ((h.mb_aff_frame != 0 || (s.picture_structure != Constants.PICT_FRAME)) ? 1 : 0) >= s.mb_num ||
               first_mb_in_slice >= s.mb_num)
            {
                //av_log(h.s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");
                // DebugTool.printDebugString("   --- decode_slide_header error case 10\n");
                return -70;
            }
            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) << ((h.mb_aff_frame != 0 || (s.picture_structure != Constants.PICT_FRAME)) ? 1 : 0);
            if (s.picture_structure == Constants.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 == Constants.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)
            {
                s.gb.get_ue_golomb("idr_pic_id"); /* idr_pic_id */
            }

            if (h.sps.poc_type == 0)
            {
                h.poc_lsb = (int)s.gb.get_bits(h.sps.log2_max_poc_lsb, "poc_lsb");

                if (h.pps.pic_order_present == 1 && s.picture_structure == Constants.PICT_FRAME)
                {
                    h.delta_poc_bottom = s.gb.get_se_golomb("delta_poc_bottom");
                }
            }

            if (h.sps.poc_type == 1 && 0 == h.sps.delta_pic_order_always_zero_flag)
            {
                h.delta_poc[0] = s.gb.get_se_golomb("delta_poc[0]");

                if (h.pps.pic_order_present == 1 && s.picture_structure == Constants.PICT_FRAME)
                    h.delta_poc[1] = s.gb.get_se_golomb("delta_poc[1]");
            }

            h.init_poc();

            if (h.pps.redundant_pic_cnt_present != 0)
            {
                h.redundant_pic_count = s.gb.get_ue_golomb("redundant_pic_count");
            }

            //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)
            {
                if (h.slice_type_nos == FF_B_TYPE)
                {
                    h.direct_spatial_mv_pred = (int)s.gb.get_bits1("direct_spatial_mv_pred");
                }
                num_ref_idx_active_override_flag = (int)s.gb.get_bits1("num_ref_idx_active_override_flag");

                if (num_ref_idx_active_override_flag != 0)
                {
                    h.ref_count[0] = s.gb.get_ue_golomb("ref_count[0]") + 1;
                    if (h.slice_type_nos == FF_B_TYPE)
                        h.ref_count[1] = s.gb.get_ue_golomb("ref_count[1]") + 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;
                        // DebugTool.printDebugString("   --- decode_slide_header error case 11\n");

                        return -71;
                    }
                }
                if (h.slice_type_nos == FF_B_TYPE)
                    h.list_count = 2;
                else
                    h.list_count = 1;
            }
            else
                h.list_count = 0;

            if (0 == default_ref_list_done)
            {
                h.ff_h264_fill_default_ref_list();
            }

            if (h.slice_type_nos != FF_I_TYPE && h.ff_h264_decode_ref_pic_list_reordering() < 0)
            {
                // DebugTool.printDebugString("   --- decode_slide_header error case 12\n");

                return -72;
            }

            if (h.slice_type_nos != FF_I_TYPE)
            {
                s.last_picture_ptr = h.ref_list[0][0];
                MpegEncContext.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];
                MpegEncContext.ff_copy_picture(s.next_picture, s.next_picture_ptr);
            }

            if ((h.pps.weighted_pred != 0 && h.slice_type_nos == FF_P_TYPE)
               || (h.pps.weighted_bipred_idc == 1 && h.slice_type_nos == FF_B_TYPE))
                h.pred_weight_table();
            else if (h.pps.weighted_bipred_idc == 2 && h.slice_type_nos == FF_B_TYPE)
            {
                h.implicit_weight_table(-1);
            }
            else
            {
                h.use_weight = 0;
                for (i = 0; i < 2; i++)
                {
                    h.luma_weight_flag[i] = 0;
                    h.chroma_weight_flag[i] = 0;
                }
            }

            if (h.nal_ref_idc != 0)
                h0.ff_h264_decode_ref_pic_marking(s.gb);

            if (h.mb_aff_frame != 0)
            {
                h.ff_h264_fill_mbaff_ref_list();

                if (h.pps.weighted_bipred_idc == 2 && h.slice_type_nos == FF_B_TYPE)
                {
                    h.implicit_weight_table(0);
                    h.implicit_weight_table(1);
                }
            }

            if (h.slice_type_nos == FF_B_TYPE && 0 == h.direct_spatial_mv_pred)
                h.ff_h264_direct_dist_scale_factor();
            h.ff_h264_direct_ref_list_init();

            if (h.slice_type_nos != FF_I_TYPE && h.pps.cabac != 0)
            {
                tmp = s.gb.get_ue_golomb_31("cabac_init_idc");
                if (tmp > 2)
                {
                    //av_log(s.avctx, AV_LOG_ERROR, "cabac_init_idc overflow\n");
                    // DebugTool.printDebugString("   --- decode_slide_header error case 13\n");

                    return -73;
                }
                h.cabac_init_idc = tmp;
            }

            h.last_qscale_diff = 0;
            tmp = h.pps.init_qp + s.gb.get_se_golomb("init_qp");
            if (tmp > 51)
            {
                //av_log(s.avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
                // DebugTool.printDebugString("   --- decode_slide_header error case 14\n");

                return -74;
            }
            s.qscale = tmp;
            h.chroma_qp[0] = h.pps.chroma_qp_table[0][s.qscale];
            h.chroma_qp[1] = h.pps.chroma_qp_table[1][s.qscale];
            //FIXME qscale / qp ... stuff
            if (h.slice_type == FF_SP_TYPE)
            {
                s.gb.get_bits1("sp_for_switch_flag"); /* sp_for_switch_flag */
            }
            if (h.slice_type == FF_SP_TYPE || h.slice_type == FF_SI_TYPE)
            {
                s.gb.get_se_golomb("slice_qs_delta"); /* slice_qs_delta */
            }

            h.deblocking_filter = 1;
            h.slice_alpha_c0_offset = 52;
            h.slice_beta_offset = 52;
            if (0 != h.pps.deblocking_filter_parameters_present)
            {
                tmp = s.gb.get_ue_golomb_31("deblocking_filter_idc");
                if (tmp > 2)
                {
                    // DebugTool.printDebugString("   --- decode_slide_header error case 15\n");

                    //av_log(s.avctx, AV_LOG_ERROR, "deblocking_filter_idc %u out of range\n", tmp);
                    return -75;
                }
                h.deblocking_filter = tmp;
                if (h.deblocking_filter < 2)
                    h.deblocking_filter ^= 1; // 1<->0

                if (0 != h.deblocking_filter)
                {
                    h.slice_alpha_c0_offset += s.gb.get_se_golomb("slice_alpha_c0_offset") << 1;
                    h.slice_beta_offset += s.gb.get_se_golomb("slice_beta_offset") << 1;
                    if (h.slice_alpha_c0_offset > 104
                       || h.slice_beta_offset > 104)
                    {
                        // DebugTool.printDebugString("   --- decode_slide_header error case 16\n");

                        //av_log(s.avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", h.slice_alpha_c0_offset, h.slice_beta_offset);
                        return -76;
                    }
                }
            }

            if (s.skip_loop_filter >= MpegEncContext.AVDISCARD_ALL
               || (s.skip_loop_filter >= MpegEncContext.AVDISCARD_NONKEY && h.slice_type_nos != FF_I_TYPE)
               || (s.skip_loop_filter >= MpegEncContext.AVDISCARD_BIDIR && h.slice_type_nos == FF_B_TYPE)
               || (s.skip_loop_filter >= MpegEncContext.AVDISCARD_NONREF && h.nal_ref_idc == 0))
                h.deblocking_filter = 0;

            if (h.deblocking_filter == 1 && h0.max_contexts > 1)
            {
                if ((s.flags2 & MpegEncContext.CODEC_FLAG2_FAST) != 0)
                {
                    /* Cheat slightly for speed:
                       Do not bother to deblock across slices. */
                    h.deblocking_filter = 2;
                }
                else
                {
                    h0.max_contexts = 1;
                    if (0 == 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)
                    {
                        // DebugTool.printDebugString("   --- decode_slide_header error case 17\n");
                        return 1; // deblocking switched inside frame
                    }
                }
            }
            h.qp_thresh = 15 + 52 - Math.Min(h.slice_alpha_c0_offset, h.slice_beta_offset) - Math.Max(Math.Max(0, h.pps.chroma_qp_index_offset[0]), h.pps.chroma_qp_index_offset[1]);
            /*
                #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= s.gb.get_bits( ?);
                #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");
            }

            for (j = 0; j < 2; j++)
            {
                int[] id_list = new int[16];
                int[] ref2frm = h.ref2frm[h.slice_num & (MAX_SLICES - 1)][j];
                for (i = 0; i < 16; i++)
                {
                    id_list[i] = 60;
                    if (h.ref_list[j][i].data_base[0] != null)
                    {
                        int k;
                        //uint8_t *base= h.ref_list[j][i].base[0];
                        byte[] @base = h.ref_list[j][i].@base[0];
                        for (k = 0; k < h.short_ref_count; k++)
                            if (h.short_ref[k].@base[0] == @base)
                            {
                                id_list[i] = k;
                                break;
                            }
                        for (k = 0; k < h.long_ref_count; k++)
                            if (h.long_ref[k] != null && h.long_ref[k].@base[0] == @base)
                            {
                                id_list[i] = h.short_ref_count + k;
                                break;
                            }
                    }
                }

                ref2frm[0] =
                ref2frm[1] = -1;
                for (i = 0; i < 16; i++)
                    ref2frm[i + 2] = 4 * id_list[i]
                                  + (h.ref_list[j][i].reference & 3);
                ref2frm[18 + 0] =
                ref2frm[18 + 1] = -1;
                for (i = 16; i < 48; i++)
                    ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1]
                                  + (h.ref_list[j][i].reference & 3);
            }

            h.emu_edge_width = ((s.flags & MpegEncContext.CODEC_FLAG_EMU_EDGE) != 0 ? 0 : 16);
            h.emu_edge_height = (0 != h.mb_aff_frame || (s.picture_structure != Constants.PICT_FRAME)) ? 0 : h.emu_edge_width;

            /* No debug
            if((s.debug&FF_DEBUG_PICT_INFO)!=0){
                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-26, h.slice_beta_offset/2-26,
                       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") : ""
                       );
            }
            */
            // DebugTool.printDebugString("   --- decode_slide_header OK\n");
            return 0;
        }
Beispiel #21
0
 public static void dumpDebugFrameData(H264Context h, string msg)
 {
     if (!DEBUG_MODE) return;
     dumpDebugFrameData(h, msg, true);
 }