⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t264enc.c

📁 T264是中国的视频编码自由组织合力开发的264编解码程序
💻 C
📖 第 1 页 / 共 4 页
字号:
        t->mb.nnz_ref[NNZ_LUMA - 1 + 8]  =
        t->mb.nnz_ref[NNZ_LUMA - 1 + 16] =
        t->mb.nnz_ref[NNZ_LUMA - 1 + 24] = 0x80;

        t->mb.nnz_ref[NNZ_CHROMA0 - 1 + 0] =
        t->mb.nnz_ref[NNZ_CHROMA0 - 1 + 8] =
        t->mb.nnz_ref[NNZ_CHROMA1 - 1 + 0] =
        t->mb.nnz_ref[NNZ_CHROMA1 - 1 + 8] = 0x80;
    }
    if (mb_x > 0 && mb_y > 0)
    {
        int32_t lefttop_xy = t->mb.mb_xy - t->mb_stride - 1;
        t->mb.vec_ref[0].vec[0] = t->rec->mb[lefttop_xy].vec[0][15];
        t->mb.vec_ref[0].vec[1] = t->rec->mb[lefttop_xy].vec[1][15];
        t->mb.vec_ref[0].subpart = t->rec->mb[lefttop_xy].submb_part[15];
        t->mb.vec_ref[0].part = t->rec->mb[lefttop_xy].mb_part;
    }
	//for CABAC
	t->mb.mb_mode_uv = Intra_8x8_DC;
#undef INITINVALIDVEC
}

void
T264_mb_save_context(T264_t* t)
{
    memcpy(t->mb.context, &t->mb, sizeof(*t->mb.context));
}

static void
T264_reset_ref(T264_t* t)
{
    int32_t i;

    for(i = 1 ; i < MAX_REFFRAMES ; i ++)
    {
        t->refn[i].poc = -1;
    }
    t->rec = &t->refn[0];
    t->refn[0].poc = 0;
}

static void
T264_load_ref(T264_t* t)
{
    int32_t i;

    t->refl0_num = 0;
    t->refl1_num = 0;
    if (t->slice_type == SLICE_P)
    {
        for(i = 0 ; i < t->param.ref_num ; i ++)
        {
            if (t->refn[i + 1].poc >= 0)
            {
                t->ref[0][t->refl0_num ++] = &t->refn[i + 1];
            }
        }
    }
    else if (t->slice_type == SLICE_B)
    {
        for(i = 0 ; i < t->param.ref_num; i ++)
        {
            if (t->refn[i + 1].poc < t->cur.poc)
            {
                if (t->refn[i + 1].poc >= 0)
                    t->ref[0][t->refl0_num ++] = &t->refn[i + 1];
            }
            else
            {
                // yes, t->refn[i].poc already > 0
                t->ref[1][t->refl1_num ++] = &t->refn[i + 1];
            }
        }
    }
}

void
T264_extend_border(T264_t* t, T264_frame_t* f)
{
    int32_t i;
    uint8_t* py0;
    uint8_t* pu;
    uint8_t* pv;
    uint8_t* tmpy0;
    uint8_t* tmpu;
    uint8_t* tmpv;

    // top, top-left, top-right
    py0 = f->Y[0] - t->edged_stride;
    pu = f->U - t->edged_stride_uv;
    pv = f->V - t->edged_stride_uv;
    for(i = 0 ; i < (EDGED_HEIGHT >> 1) ; i ++)
    {
        // y
        memcpy(py0, f->Y[0], t->stride);
        memset(py0 - EDGED_WIDTH, f->Y[0][0], EDGED_WIDTH);
        memset(py0 + t->stride, f->Y[0][t->stride - 1], EDGED_WIDTH);
        py0 -= t->edged_stride;

        memcpy(py0, f->Y[0], t->stride);
        memset(py0 - EDGED_WIDTH, f->Y[0][0], EDGED_WIDTH);
        memset(py0 + t->stride, f->Y[0][t->stride - 1], EDGED_WIDTH);
        py0 -= t->edged_stride;

        // u
        memcpy(pu, f->U, t->stride_uv);
        memset(pu - (EDGED_WIDTH >> 1), f->U[0], EDGED_WIDTH >> 1);
        memset(pu + t->stride_uv, f->U[t->stride_uv - 1], EDGED_WIDTH >> 1);
        pu -= t->edged_stride_uv;

        // V
        memcpy(pv, f->V, t->stride_uv);
        memset(pv - (EDGED_WIDTH >> 1), f->V[0], EDGED_WIDTH >> 1);
        memset(pv + t->stride_uv, f->V[t->stride_uv - 1], EDGED_WIDTH >> 1);
        pv -= t->edged_stride_uv;
    }

    // left & right
    py0 = f->Y[0] - EDGED_WIDTH;
    pu = f->U - (EDGED_WIDTH >> 1);
    pv = f->V - (EDGED_WIDTH >> 1);
    for(i = 0 ; i < (t->height >> 1) ; i ++)
    {
        // left
        memset(py0, py0[EDGED_WIDTH], EDGED_WIDTH);
        // right
        memset(&py0[t->stride + EDGED_WIDTH], py0[t->stride + EDGED_WIDTH - 1], EDGED_WIDTH);
        py0 += t->edged_stride;

        memset(py0, py0[EDGED_WIDTH], EDGED_WIDTH);
        memset(&py0[t->stride + EDGED_WIDTH], py0[t->stride + EDGED_WIDTH - 1], EDGED_WIDTH);
        py0 += t->edged_stride;

        // u
        memset(pu, pu[EDGED_WIDTH >> 1], EDGED_WIDTH >> 1);
        memset(&pu[t->stride_uv + (EDGED_WIDTH >> 1)], pu[t->stride_uv + (EDGED_WIDTH >> 1) - 1], EDGED_WIDTH >> 1);
        pu += t->edged_stride_uv;

        // v
        memset(pv, pv[EDGED_WIDTH >> 1], EDGED_WIDTH >> 1);
        memset(&pv[t->stride_uv + (EDGED_WIDTH >> 1)], pv[t->stride_uv + (EDGED_WIDTH >> 1) - 1], EDGED_WIDTH >> 1);
        pv += t->edged_stride_uv;
    }

    // bottom, left-bottom,right-bottom
    py0 = f->Y[0] + t->edged_stride * t->height;
    tmpy0 = f->Y[0] + t->edged_stride * (t->height - 1);
    pu = f->U + t->edged_stride_uv * (t->height >> 1);
    tmpu = f->U + t->edged_stride_uv * ((t->height >> 1) - 1);
    pv = f->V + t->edged_stride_uv * (t->height >> 1);
    tmpv = f->V + t->edged_stride_uv * ((t->height >> 1)- 1);
    for(i = 0 ; i < (EDGED_HEIGHT >> 1) ; i ++)
    {
        // y
        memcpy(py0, tmpy0, t->stride);
        memset(py0 - EDGED_WIDTH, tmpy0[0], EDGED_WIDTH);
        memset(py0 + t->stride, tmpy0[t->stride - 1], EDGED_WIDTH);
        py0 += t->edged_stride;

        memcpy(py0, tmpy0, t->stride);
        memset(py0 - EDGED_WIDTH, tmpy0[0], EDGED_WIDTH);
        memset(py0 + t->stride, tmpy0[t->stride - 1], EDGED_WIDTH);
        py0 += t->edged_stride;

        // u
        memcpy(pu, tmpu, t->stride_uv);
        memset(pu - (EDGED_WIDTH >> 1), tmpu[0], EDGED_WIDTH >> 1);
        memset(pu + t->stride_uv, tmpu[t->stride_uv - 1], EDGED_WIDTH >> 1);
        pu += t->edged_stride_uv;

        // v
        memcpy(pv, tmpv, t->stride_uv);
        memset(pv - (EDGED_WIDTH >> 1), tmpv[0], EDGED_WIDTH >> 1);
        memset(pv + t->stride_uv, tmpv[t->stride_uv - 1], EDGED_WIDTH >> 1);
        pv += t->edged_stride_uv;
    }
}

void
T264_interpolate_halfpel(T264_t* t, T264_frame_t* f)
{
    int32_t src_offset;
    int32_t width, height;

    if (t->flags & (USE_HALFPEL| USE_QUARTPEL))
    {
        src_offset = - 3;
        width      = t->width + 3 + 2;
        height     = t->height;
        t->interpolate_halfpel_h(f->Y[0] + src_offset, t->edged_stride, f->Y[1] + src_offset, t->edged_stride, width, height);
        // extend border
        {
            uint8_t* src, *dst;
            int32_t i;
            // left & right
            dst = f->Y[1] - EDGED_WIDTH;
            src = f->Y[1] - 3;
            for(i = 0 ; i < t->height ; i ++)
            {
                // left
                memset(dst, src[0], EDGED_WIDTH - 3);
                // right
                memset(&dst[t->stride + EDGED_WIDTH + 2], src[t->stride - 1 + 3 + 2], EDGED_WIDTH - 2);
                dst += t->edged_stride;
                src += t->edged_stride;
            }
            // top
            dst = f->Y[1] - EDGED_HEIGHT * t->edged_stride - EDGED_WIDTH;
            src = f->Y[1] - EDGED_WIDTH;
            for(i = 0 ; i < EDGED_HEIGHT ; i ++)
            {
                memcpy(dst, src, t->edged_stride);
                dst += t->edged_stride;
            }
            // bottom
            src = f->Y[1] + (t->height - 1) * t->edged_stride - EDGED_WIDTH;
            dst = src + t->edged_stride;
            for(i = 0 ; i < EDGED_HEIGHT ; i ++)
            {
                memcpy(dst, src, t->edged_stride);
                dst += t->edged_stride;
            }
        }
        src_offset = - 3 * t->edged_stride;
        width      = t->width;
        height     = t->height + 3 + 2;
        t->interpolate_halfpel_v(f->Y[0] + src_offset, t->edged_stride, f->Y[2] + src_offset, t->edged_stride, width, height);
        // extend border
        {
            uint8_t* src, *dst;
            int32_t i;
            // left & right
            dst = f->Y[2] - 3 * t->edged_stride - EDGED_WIDTH;
            src = f->Y[2] - 3 * t->edged_stride;
            for(i = 0 ; i < t->height + 3 + 2 ; i ++)
            {
                // left
                memset(dst, src[0], EDGED_WIDTH);
                // right
                memset(&dst[t->stride + EDGED_WIDTH], src[t->stride - 1], EDGED_WIDTH);
                dst += t->edged_stride;
                src += t->edged_stride;
            }
            // top
            dst = f->Y[2] - EDGED_HEIGHT * t->edged_stride - EDGED_WIDTH;
            src = f->Y[2] - 3 * t->edged_stride - EDGED_WIDTH;
            for(i = 0 ; i < EDGED_HEIGHT - 3 ; i ++)
            {
                memcpy(dst, src, t->edged_stride);
                dst += t->edged_stride;
            }
            // bottom
            src = f->Y[2] + (t->height + 2 - 1) * t->edged_stride - EDGED_WIDTH;
            dst = src + t->edged_stride;
            for(i = 0 ; i < EDGED_HEIGHT - 2 ; i ++)
            {
                memcpy(dst, src, t->edged_stride);
                dst += t->edged_stride;
            }
        }
        if (t->flags & USE_FASTINTERPOLATE)
        {
            // NOTE: here just offset -3 is not enough to complete reverting the origin implemention
            //   in Y[2] its border is already extend 3 + 2, the idea border in Y[3] is -3 -3 2 2
            // If u use USE_FASTINTERPOLATE we prefer the speed is the first condition we do not extend the border further
            src_offset = - 3;
            width      = t->width + 3 + 2;
            height     = t->height;
            t->interpolate_halfpel_h(f->Y[2] + src_offset, t->edged_stride, f->Y[3] + src_offset, t->edged_stride, width, height);
            // extend border
            {
                uint8_t* src, *dst;
                int32_t i;
                // left & right
                dst = f->Y[3] - EDGED_WIDTH;
                src = f->Y[3] - 3;
                for(i = 0 ; i < t->height ; i ++)
                {
                    // left
                    memset(dst, src[0], EDGED_WIDTH - 3);
                    // right
                    memset(&dst[t->stride + EDGED_WIDTH + 2], src[t->stride - 1 + 3 + 2], EDGED_WIDTH - 2);
                    dst += t->edged_stride;
                    src += t->edged_stride;
                }
                // top
                dst = f->Y[3] - EDGED_HEIGHT * t->edged_stride - EDGED_WIDTH;
                src = f->Y[3] - EDGED_WIDTH;
                for(i = 0 ; i < EDGED_HEIGHT ; i ++)
                {
                    memcpy(dst, src, t->edged_stride);
                    dst += t->edged_stride;
                }
                // bottom
                src = f->Y[3] + (t->height - 1) * t->edged_stride - EDGED_WIDTH;
                dst = src + t->edged_stride;
                for(i = 0 ; i < EDGED_HEIGHT ; i ++)
                {
                    memcpy(dst, src, t->edged_stride);
                    dst += t->edged_stride;
                }
            }
        }
        else
        {
            src_offset = - 3 * t->edged_stride - 3;
            width      = t->width + 3 + 2;
            height     = t->height + 3 + 2;
            t->interpolate_halfpel_hv(f->Y[0] + src_offset, t->edged_stride, f->Y[3] + src_offset, t->edged_stride, width, height);
            // extend border
            {
                uint8_t* src, *dst;
                int32_t i;
                // left & right
                dst = f->Y[3] - 3 * t->edged_stride - EDGED_WIDTH;
                src = f->Y[3] - 3 * t->edged_stride - 3;
                for(i = 0 ; i < t->height + 3 + 2 ; i ++)
                {
                    // left
                    memset(dst, src[0], EDGED_WIDTH - 3);
                    // right
                    memset(&dst[t->stride + EDGED_WIDTH + 2], src[t->stride - 1 + 3 + 2], EDGED_WIDTH - 2);
                    dst += t->edged_stride;
                    src += t->edged_stride;
                }
                // top
                dst = f->Y[3] - EDGED_HEIGHT * t->edged_stride - EDGED_WIDTH;
                src = f->Y[3] - 3 * t->edged_stride - EDGED_WIDTH;
                for(i = 0 ; i < EDGED_HEIGHT - 3 ; i ++)
                {
                    memcpy(dst, src, t->edged_stride);
                    dst += t->edged_stride;
                }
                // bottom
                src = f->Y[3] + (t->height + 2 - 1) * t->edged_stride - EDGED_WIDTH;
                dst = src + t->edged_stride;
                for(i = 0 ; i < EDGED_HEIGHT - 2 ; i ++)
                {
                    memcpy(dst, src, t->edged_stride);
                    dst += t->edged_stride;
                }
            }
        }
    }
}

static void
T264_save_ref(T264_t* t)
{
    int32_t i;
    T264_frame_t tmp;
    /* deblock filter exec here */
    if (t->param.disable_filter == 0)
        T264_deblock_frame(t, t->rec);
    /* current only del with i,p */
    T264_extend_border(t, t->rec);
    T264_interpolate_halfpel(t, t->rec);

    tmp = t->refn[t->param.ref_num];
    t->refn[0].poc = t->poc;
    for(i = t->param.ref_num ; i >= 1 ; i --)
    {
        t->refn[i] = t->refn[i - 1];
    }

    t->refn[0] = tmp;
    t->rec = &t->refn[0];
}

void
T264_mb_mode_decision(T264_t* t)
{
    if(t->slice_type == SLICE_P)
    {
        T264_mode_decision_interp_y(t);
    }
    else if(t->slice_type == SLICE_B)
    {
        T264_mode_decision_interb_y(t);
    }
    else if (t->slice_type == SLICE_I)
    {
        T264_mode_decision_intra_y(t);
    }
}

void
T264_mb_encode(T264_t* t)
{
    if(t->mb.mb_mode == P_MODE)
    {
        T264_encode_inter_y(t);
        T264_encode_inter_uv(t);

        t->stat.p_block_num[t->mb.mb_part] ++;
    }
    else if(t->mb.mb_mode == P_SKIP)
    {
        t->stat.skip_block_num++;
    }
    else if (t->mb.mb_mode == B_MODE)
    {
        T264_encode_inter_y(t);
        T264_encode_interb_uv(t);

        t->stat.p_block_num[0] ++;
    }
    else if (t->mb.mb_mode == I_4x4 || t->mb.mb_mode == I_16x16)
    {
        T264_encode_intra_y(t);

        //
        // Chroma
        //
        T264_mode_decision_intra_uv(t);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -