Beispiel #1
0
        public void mc_part_weighted(int n, int square, int chroma_height, int delta,
            byte[] dest_y_base, int dest_y_offset,
            byte[] dest_cb_base, int dest_cb_offset,
            byte[] dest_cr_base, int dest_cr_offset,
            int x_offset, int y_offset,
            DSPContext.Ih264_qpel_mc_func[] qpix_put, DSPContext.Ih264_chroma_mc_func chroma_put,
            H264DSPContext.IH264WeightFunctionStub luma_weight_op, H264DSPContext.IH264WeightFunctionStub chroma_weight_op,
            H264DSPContext.IH264BiWeightFunctionStub luma_weight_avg, H264DSPContext.IH264BiWeightFunctionStub chroma_weight_avg,
            int list0, int list1)
        {
            dest_y_offset += 2 * x_offset + 2 * y_offset * this.mb_linesize;
            dest_cb_offset += x_offset + y_offset * this.mb_uvlinesize;
            dest_cr_offset += x_offset + y_offset * this.mb_uvlinesize;
            x_offset += 8 * s.mb_x;
            y_offset += 8 * (s.mb_y >> mb_field_decoding_flag);

            if (list0 != 0 && list1 != 0)
            {
                /* don't optimize for luma-only case, since B-frames usually
                * use implicit weights => chroma too. */
                byte[] tmp_cb_base = s.obmc_scratchpad;
                int tmp_cb_offset = 0;
                byte[] tmp_cr_base = s.obmc_scratchpad;
                int tmp_cr_offset = 8;
                byte[] tmp_y_base = s.obmc_scratchpad;
                int tmp_y_offset = 8 * this.mb_uvlinesize;
                int refn0 = this.ref_cache[0][scan8[n]];
                int refn1 = this.ref_cache[1][scan8[n]];

                mc_dir_part(this.ref_list[0][refn0], n, square, chroma_height, delta, 0,
                        dest_y_base, dest_y_offset,
                        dest_cb_base, dest_cb_offset,
                        dest_cr_base, dest_cr_offset,
                     x_offset, y_offset, qpix_put, chroma_put);
                mc_dir_part(this.ref_list[1][refn1], n, square, chroma_height, delta, 1,
                        tmp_y_base, tmp_y_offset,
                        tmp_cb_base, tmp_cb_offset,
                        tmp_cr_base, tmp_cr_offset,
                     x_offset, y_offset, qpix_put, chroma_put);

                if (this.use_weight == 2)
                {
                    int weight0 = this.implicit_weight[refn0][refn1][s.mb_y & 1];
                    int weight1 = 64 - weight0;
                    luma_weight_avg(dest_y_base, dest_y_offset, tmp_y_base, tmp_y_offset, this.mb_linesize, 5, weight0, weight1, 0);
                    chroma_weight_avg(dest_cb_base, dest_cb_offset, tmp_cb_base, tmp_cb_offset, this.mb_uvlinesize, 5, weight0, weight1, 0);
                    chroma_weight_avg(dest_cr_base, dest_cr_offset, tmp_cr_base, tmp_cr_offset, this.mb_uvlinesize, 5, weight0, weight1, 0);
                }
                else
                {
                    luma_weight_avg(dest_y_base, dest_y_offset, tmp_y_base, tmp_y_offset, this.mb_linesize, this.luma_log2_weight_denom,
                                 this.luma_weight[refn0][0][0], this.luma_weight[refn1][1][0],
                                 this.luma_weight[refn0][0][1] + this.luma_weight[refn1][1][1]);
                    chroma_weight_avg(dest_cb_base, dest_cb_offset, tmp_cb_base, tmp_cb_offset, this.mb_uvlinesize, this.chroma_log2_weight_denom,
                                 this.chroma_weight[refn0][0][0][0], this.chroma_weight[refn1][1][0][0],
                                 this.chroma_weight[refn0][0][0][1] + this.chroma_weight[refn1][1][0][1]);
                    chroma_weight_avg(dest_cr_base, dest_cr_offset, tmp_cr_base, tmp_cr_offset, this.mb_uvlinesize, this.chroma_log2_weight_denom,
                                 this.chroma_weight[refn0][0][1][0], this.chroma_weight[refn1][1][1][0],
                                 this.chroma_weight[refn0][0][1][1] + this.chroma_weight[refn1][1][1][1]);
                }
            }
            else
            {
                int list = (list1 != 0 ? 1 : 0);
                int refn = this.ref_cache[list][scan8[n]];
                AVFrame @ref = this.ref_list[list][refn];
                mc_dir_part(@ref, n, square, chroma_height, delta, list,
                        dest_y_base, dest_y_offset,
                        dest_cb_base, dest_cb_offset,
                        dest_cr_base, dest_cr_offset,
                     x_offset, y_offset,
                     qpix_put, chroma_put);

                luma_weight_op(dest_y_base, dest_y_offset, this.mb_linesize, this.luma_log2_weight_denom,
                        this.luma_weight[refn][list][0], this.luma_weight[refn][list][1]);
                if (this.use_weight_chroma != 0)
                {
                    chroma_weight_op(dest_cb_base, dest_cb_offset, this.mb_uvlinesize, this.chroma_log2_weight_denom,
                                  this.chroma_weight[refn][list][0][0], this.chroma_weight[refn][list][0][1]);
                    chroma_weight_op(dest_cr_base, dest_cr_offset, this.mb_uvlinesize, this.chroma_log2_weight_denom,
                                  this.chroma_weight[refn][list][1][0], this.chroma_weight[refn][list][1][1]);
                }
            }
        }
Beispiel #2
0
        public void mc_part_std(int n, int square, int chroma_height, int delta,
            byte[] dest_y_base, int dest_y_offset,
            byte[] dest_cb_base, int dest_cb_offset,
            byte[] dest_cr_base, int dest_cr_offset,
            int x_offset, int y_offset,
            DSPContext.Ih264_qpel_mc_func[] qpix_put, DSPContext.Ih264_chroma_mc_func chroma_put,
            DSPContext.Ih264_qpel_mc_func[] qpix_avg, DSPContext.Ih264_chroma_mc_func chroma_avg,
            int list0, int list1)
        {
            DSPContext.Ih264_qpel_mc_func[] qpix_op = qpix_put;
            DSPContext.Ih264_chroma_mc_func chroma_op = chroma_put;

            dest_y_offset += 2 * x_offset + 2 * y_offset * this.mb_linesize;
            dest_cb_offset += x_offset + y_offset * this.mb_uvlinesize;
            dest_cr_offset += x_offset + y_offset * this.mb_uvlinesize;
            x_offset += 8 * s.mb_x;
            y_offset += 8 * (s.mb_y >> mb_field_decoding_flag);

            if (list0 != 0)
            {
                AVFrame @ref = this.ref_list[0][this.ref_cache[0][scan8[n]]];
                mc_dir_part(@ref, n, square, chroma_height, delta, 0,
                        dest_y_base, dest_y_offset,
                        dest_cb_base, dest_cb_offset,
                        dest_cr_base, dest_cr_offset,
                            x_offset, y_offset,
                            qpix_op, chroma_op);

                qpix_op = qpix_avg;
                chroma_op = chroma_avg;
            }

            if (list1 != 0)
            {
                AVFrame @ref = this.ref_list[1][this.ref_cache[1][scan8[n]]];
                mc_dir_part(@ref, n, square, chroma_height, delta, 1,
                        dest_y_base, dest_y_offset,
                        dest_cb_base, dest_cb_offset,
                        dest_cr_base, dest_cr_offset,
                            x_offset, y_offset,
                            qpix_op, chroma_op);
            }
        }
Beispiel #3
0
        ////////////////////////////////
        // Motion functions
        //public void mc_dir_part(Picture pic, int n, int square, int chroma_height, int delta, int list,
        //        uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
        //        int src_x_offset, int src_y_offset,
        //        qpel_mc_func *qpix_op, h264_chroma_mc_func chroma_op){
        public void mc_dir_part(AVFrame pic, int n, int square, int chroma_height, int delta, int list,
            byte[] dest_y_base, int dest_y_offset,
            byte[] dest_cb_base, int dest_cb_offset,
            byte[] dest_cr_base, int dest_cr_offset,
            int src_x_offset, int src_y_offset,
            DSPContext.Ih264_qpel_mc_func[] qpix_op, DSPContext.Ih264_chroma_mc_func chroma_op)
        {
            int mx = this.mv_cache[list][scan8[n]][0] + src_x_offset * 8;
            int my = this.mv_cache[list][scan8[n]][1] + src_y_offset * 8;
            int luma_xy = (mx & 3) + ((my & 3) << 2);

            //uint8_t * src_y = pic.data[0] + (mx>>2) + (my>>2)*this.mb_linesize;
            //uint8_t * src_cb, * src_cr;
            byte[] src_y_base = pic.data_base[0];
            int _src_y_offset = pic.data_offset[0] + (mx >> 2) + (my >> 2) * this.mb_linesize;
            byte[] src_cb_base;
            int src_cb_offset;
            byte[] src_cr_base;
            int src_cr_offset;

            int extra_width = this.emu_edge_width;
            int extra_height = this.emu_edge_height;
            int emu = 0;
            int full_mx = mx >> 2;
            int full_my = my >> 2;
            int pic_width = 16 * s.mb_width;
            int pic_height = 16 * s.mb_height >> mb_field_decoding_flag;

            // DebugTool.printDebugString("***mc_dir_part: src_x_offset="+src_x_offset+", src_y_offset="+src_y_offset+", list="+list+", n="+n+", mv_cache[0]="+this.mv_cache[list][ scan8[n] ][0]+", mv_cache[1]="+this.mv_cache[list][ scan8[n] ][1]+"\n");
            // DebugTool.printDebugString("***mc_dir_part: mx="+mx+", my="+my+", luma_xy="+luma_xy+", _src_y_offset="+((mx>>2) + (my>>2)*this.mb_linesize)+"\n");

            if ((mx & 7) != 0) extra_width -= 3;
            if ((my & 7) != 0) extra_height -= 3;

            if (full_mx < 0 - extra_width
            || full_my < 0 - extra_height
            || full_mx + 16/*FIXME*/ > pic_width + extra_width
            || full_my + 16/*FIXME*/ > pic_height + extra_height)
            {

                // DebugTool.printDebugString("***mc_dir_part: case 1\n");

                s.dsp.ff_emulated_edge_mc(s.allocated_edge_emu_buffer, s.edge_emu_buffer_offset
                        , src_y_base, _src_y_offset - 2 - 2 * this.mb_linesize
                        , this.mb_linesize, 16 + 5, 16 + 5/*FIXME*/
                        , full_mx - 2, full_my - 2
                        , pic_width, pic_height);

                src_y_base = s.allocated_edge_emu_buffer;
                _src_y_offset = s.edge_emu_buffer_offset + 2 + 2 * this.mb_linesize;
                emu = 1;
            }

            qpix_op[luma_xy](dest_y_base, dest_y_offset, src_y_base, _src_y_offset, this.mb_linesize); //FIXME try variable height perhaps?

            if (0 == square)
            {
                // DebugTool.printDebugString("***mc_dir_part: case 2\n");

                qpix_op[luma_xy](dest_y_base, dest_y_offset + delta, src_y_base, _src_y_offset + delta, this.mb_linesize);
            }

            //if(MpegEncContext.CONFIG_GRAY !=0 && (s.flags&MpegEncContext.CODEC_FLAG_GRAY)!=0) return;

            if (mb_field_decoding_flag != 0)
            {
                // DebugTool.printDebugString("***mc_dir_part: case 3\n");

                // chroma offset when predicting from a field of opposite parity
                my += 2 * ((s.mb_y & 1) - (pic.reference - 1));
                emu |= (((my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1)) ? 1 : 0);
            }

            src_cb_base = pic.data_base[1];
            src_cb_offset = pic.data_offset[1] + (mx >> 3) + (my >> 3) * this.mb_uvlinesize;
            src_cr_base = pic.data_base[2];
            src_cr_offset = pic.data_offset[2] + (mx >> 3) + (my >> 3) * this.mb_uvlinesize;

            if (emu != 0)
            {
                // DebugTool.printDebugString("***mc_dir_part: case 4\n");

                s.dsp.ff_emulated_edge_mc(s.allocated_edge_emu_buffer, s.edge_emu_buffer_offset, src_cb_base, src_cb_offset, this.mb_uvlinesize, 9, 9/*FIXME*/, (mx >> 3), (my >> 3), pic_width >> 1, pic_height >> 1);
                src_cb_base = s.allocated_edge_emu_buffer;
                src_cb_offset = s.edge_emu_buffer_offset;
            }
            chroma_op(dest_cb_base, dest_cb_offset, src_cb_base, src_cb_offset, this.mb_uvlinesize, chroma_height, mx & 7, my & 7);

            if (emu != 0)
            {
                // DebugTool.printDebugString("***mc_dir_part: case 5\n");

                s.dsp.ff_emulated_edge_mc(s.allocated_edge_emu_buffer, s.edge_emu_buffer_offset, src_cr_base, src_cr_offset, this.mb_uvlinesize, 9, 9/*FIXME*/, (mx >> 3), (my >> 3), pic_width >> 1, pic_height >> 1);
                src_cr_base = s.allocated_edge_emu_buffer;
                src_cr_offset = s.edge_emu_buffer_offset;
            }
            chroma_op(dest_cr_base, dest_cr_offset, src_cr_base, src_cr_offset, this.mb_uvlinesize, chroma_height, mx & 7, my & 7);
        }
Beispiel #4
0
 /*
 public void mc_part(int n, int square, int chroma_height, int delta,
         uint8_t *dest_y,
         uint8_t *dest_cb,
         uint8_t *dest_cr,
         int x_offset, int y_offset,
         qpel_mc_func *qpix_put, h264_chroma_mc_func chroma_put,
         qpel_mc_func *qpix_avg, h264_chroma_mc_func chroma_avg,
         h264_weight_func *weight_op, h264_biweight_func *weight_avg,
         int list0, int list1){
 */
 public void mc_part(int n, int square, int chroma_height, int delta,
     byte[] dest_y_base, int dest_y_offset,
     byte[] dest_cb_base, int dest_cb_offset,
     byte[] dest_cr_base, int dest_cr_offset,
     int x_offset, int y_offset,
     DSPContext.Ih264_qpel_mc_func[] qpix_put, DSPContext.Ih264_chroma_mc_func chroma_put,
     DSPContext.Ih264_qpel_mc_func[] qpix_avg, DSPContext.Ih264_chroma_mc_func chroma_avg,
     H264DSPContext.IH264WeightFunctionStub[] weight_op_base, int weight_op_offset,
     H264DSPContext.IH264BiWeightFunctionStub[] weight_avg_base, int weight_avg_offset,
     int list0, int list1)
 {
     if ((this.use_weight == 2 && list0 != 0 && list1 != 0
     && (this.implicit_weight[this.ref_cache[0][scan8[n]]][this.ref_cache[1][scan8[n]]][this.s.mb_y & 1] != 32))
     || this.use_weight == 1)
         mc_part_weighted(n, square, chroma_height, delta,
                 dest_y_base, dest_y_offset,
                 dest_cb_base, dest_cb_offset,
                 dest_cr_base, dest_cr_offset,
                   x_offset, y_offset, qpix_put, chroma_put,
                   weight_op_base[weight_op_offset + 0], weight_op_base[weight_op_offset + 3],
                   weight_avg_base[weight_avg_offset + 0], weight_avg_base[weight_avg_offset + 3]
                   , list0, list1);
     else
         mc_part_std(n, square, chroma_height, delta,
                 dest_y_base, dest_y_offset,
                 dest_cb_base, dest_cb_offset,
                 dest_cr_base, dest_cr_offset,
              x_offset, y_offset, qpix_put, chroma_put, qpix_avg, chroma_avg, list0, list1);
 }
Beispiel #5
0
        //    public void hl_motion(uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
        //           qpel_mc_func (*qpix_put)[16], h264_chroma_mc_func (*chroma_put),
        //           qpel_mc_func (*qpix_avg)[16], h264_chroma_mc_func (*chroma_avg),
        //           h264_weight_func *weight_op, h264_biweight_func *weight_avg){
        public void hl_motion(
            byte[] dest_y_base, int dest_y_offset,
            byte[] dest_cb_base, int dest_cb_offset,
            byte[] dest_cr_base, int dest_cr_offset,
            DSPContext.Ih264_qpel_mc_func[][] qpix_put, DSPContext.Ih264_chroma_mc_func[] chroma_put,
            DSPContext.Ih264_qpel_mc_func[][] qpix_avg, DSPContext.Ih264_chroma_mc_func[] chroma_avg,
            H264DSPContext.IH264WeightFunctionStub[] weight_op, H264DSPContext.IH264BiWeightFunctionStub[] weight_avg)
        {
            int mb_xy = this.mb_xy;
            int mb_type = (int)s.current_picture.mb_type_base[s.current_picture.mb_type_offset + mb_xy];

            ////assert(IS_INTER(mb_type));

            prefetch_motion(0);

            if ((mb_type & MB_TYPE_16x16) != 0)
            {
                mc_part(0, 1, 8, 0, dest_y_base, dest_y_offset
                        , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                        , 0, 0,
                        qpix_put[0], chroma_put[0], qpix_avg[0], chroma_avg[0],
                        weight_op, 0, weight_avg, 0,
                        IS_DIR(mb_type, 0, 0)
                        , IS_DIR(mb_type, 0, 1));
            }
            else if ((mb_type & MB_TYPE_16x8) != 0)
            {
                mc_part(0, 0, 4, 8, dest_y_base, dest_y_offset
                        , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                        , 0, 0,
                        qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0],
                        weight_op, 1, weight_avg, 1,
                        IS_DIR(mb_type, 0, 0)
                        , IS_DIR(mb_type, 0, 1));
                mc_part(8, 0, 4, 8, dest_y_base, dest_y_offset
                        , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                        , 0, 4,
                        qpix_put[1], chroma_put[0], qpix_avg[1], chroma_avg[0],
                        weight_op, 1, weight_avg, 1,
                        IS_DIR(mb_type, 1, 0)
                        , IS_DIR(mb_type, 1, 1));
            }
            else if ((mb_type & MB_TYPE_8x16) != 0)
            {
                mc_part(0, 0, 8, 8 * this.mb_linesize, dest_y_base, dest_y_offset
                        , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                        , 0, 0,
                         qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
                         weight_op, 2, weight_avg, 2,
                         IS_DIR(mb_type, 0, 0)
                         , IS_DIR(mb_type, 0, 1));
                mc_part(4, 0, 8, 8 * this.mb_linesize, dest_y_base, dest_y_offset
                        , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                        , 4, 0,
                         qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
                         weight_op, 2, weight_avg, 2,
                         IS_DIR(mb_type, 1, 0)
                         , IS_DIR(mb_type, 1, 1));
            }
            else
            {
                int i;

                ////assert(IS_8X8(mb_type));

                for (i = 0; i < 4; i++)
                {
                    int sub_mb_type = this.sub_mb_type[i];
                    int n = 4 * i;
                    int x_offset = (i & 1) << 2;
                    int y_offset = (i & 2) << 1;

                    if ((sub_mb_type & MB_TYPE_16x16) != 0)
                    {
                        mc_part(n, 1, 4, 0, dest_y_base, dest_y_offset
                                   , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                                   , x_offset, y_offset,
                                    qpix_put[1], chroma_put[1], qpix_avg[1], chroma_avg[1],
                                    weight_op, 3, weight_avg, 3,
                                    IS_DIR(sub_mb_type, 0, 0)
                                    , IS_DIR(sub_mb_type, 0, 1));
                    }
                    else if ((sub_mb_type & MB_TYPE_16x8) != 0)
                    {
                        mc_part(n, 0, 2, 4, dest_y_base, dest_y_offset
                                   , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                                   , x_offset, y_offset,
                                    qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1],
                                    weight_op, 4, weight_avg, 4,
                                    IS_DIR(sub_mb_type, 0, 0)
                                    , IS_DIR(sub_mb_type, 0, 1));
                        mc_part(n + 2, 0, 2, 4, dest_y_base, dest_y_offset
                                   , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                                   , x_offset, y_offset + 2,
                                    qpix_put[2], chroma_put[1], qpix_avg[2], chroma_avg[1],
                                    weight_op, 4, weight_avg, 4,
                                    IS_DIR(sub_mb_type, 0, 0)
                                    , IS_DIR(sub_mb_type, 0, 1));
                    }
                    else if ((sub_mb_type & MB_TYPE_8x16) != 0)
                    {
                        mc_part(n, 0, 4, 4 * this.mb_linesize, dest_y_base, dest_y_offset
                                   , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                                   , x_offset, y_offset,
                                    qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
                                    weight_op, 5, weight_avg, 5,
                                    IS_DIR(sub_mb_type, 0, 0)
                                    , IS_DIR(sub_mb_type, 0, 1));
                        mc_part(n + 1, 0, 4, 4 * this.mb_linesize, dest_y_base, dest_y_offset
                                   , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                                   , x_offset + 2, y_offset,
                                    qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
                                    weight_op, 5, weight_avg, 5,
                                    IS_DIR(sub_mb_type, 0, 0)
                                    , IS_DIR(sub_mb_type, 0, 1));
                    }
                    else
                    {
                        int j;
                        ////assert(IS_SUB_4X4(sub_mb_type));
                        for (j = 0; j < 4; j++)
                        {
                            int sub_x_offset = x_offset + 2 * (j & 1);
                            int sub_y_offset = y_offset + (j & 2);
                            mc_part(n + j, 1, 2, 0, dest_y_base, dest_y_offset
                                       , dest_cb_base, dest_cb_offset, dest_cr_base, dest_cr_offset
                                       , sub_x_offset, sub_y_offset,
                                        qpix_put[2], chroma_put[2], qpix_avg[2], chroma_avg[2],
                                        weight_op, 6, weight_avg, 6,
                                        IS_DIR(sub_mb_type, 0, 0)
                                        , IS_DIR(sub_mb_type, 0, 1));
                        }
                    }
                }
            }
            prefetch_motion(1);
        }