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

📄 inter_b.c

📁 T264是中国的视频编码自由组织合力开发的264编解码程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
*
*  T264 AVC CODEC
*
*  Copyright(C) 2004-2005 llcc <lcgate1@yahoo.com.cn>
*               2004-2005 visionany <visionany@yahoo.com.cn>
*	2005.1.5 CloudWu<sywu@sohu.com> Modify T264_get_direct_mv
*  This program is free software ; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation ; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY ; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program ; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
*
****************************************************************************/
#include "portab.h"
#include "stdio.h"
#ifndef CHIP_DM642
#include "memory.h"
#endif
#include "T264.h"
#include "inter.h"
#include "inter_b.h"
#include "intra.h"
#include "estimation.h"
#include "utility.h"
#include "interpolate.h"
#include "bitstream.h"
#include <assert.h>
#include "block.h"

static int32_t __inline
T264_detect_direct_16x16(T264_t* t)
{
    T264_vector_t vec_direct[2][16];

    T264_get_direct_mv(t, vec_direct);

    if (memcmp(vec_direct, t->mb.vec, sizeof(vec_direct)) == 0)
    {
        return 1;
    }

    return 0;
}

uint32_t
T264_mode_decision_interb_y(_RW T264_t* t)
{
    DECLARE_ALIGNED_MATRIX(pred_8x8, 16, 16, uint8_t, CACHE_SIZE);
    DECLARE_ALIGNED_MATRIX(pred_16x8, 16, 16, uint8_t, CACHE_SIZE);
    DECLARE_ALIGNED_MATRIX(pred_8x16, 16, 16, uint8_t, CACHE_SIZE);
	DECLARE_ALIGNED_MATRIX(pred_p16x16, 16, 16, uint8_t, CACHE_SIZE);
    uint32_t sad;
    uint32_t sad_16x8;
    uint32_t sad_8x16;
	uint32_t sad_16x16;
    uint32_t sad_min;
    uint8_t sub_part[4];
    uint8_t part;
    uint8_t part_16x8[2];
    uint8_t part_8x16[2];
    uint8_t* p_min = t->mb.pred_p16x16;
	uint32_t	i,j;

    T264_vector_t vec_16x16[2][2], vec_8x8[4][2];
    T264_vector_t vec_16x8[2][2];
    T264_vector_t vec_8x16[2][2];
    T264_vector_t vec_4x4[2][16];

    sad_min = T264_mode_decision_inter_16x16b(t, vec_16x16, t->mb.pred_p16x16, &part);
    t->mb.mb_mode = B_MODE;
    copy_nvec(&vec_16x16[0][0], &t->mb.vec[0][0], 4, 4, 4);
    copy_nvec(&vec_16x16[0][1], &t->mb.vec[1][0], 4, 4, 4);
    t->mb.mb_part = MB_16x16;
    t->mb.mb_part2[0] = part;
/*
    if (t->mb.is_copy)
    {
        t->mb.sad = sad_min;
        
        return sad_min;
    }
    */

    if (t->param.block_size & SEARCH_16x8B)
    {
        vec_16x8[0][0].refno = vec_16x16[0][0].refno;
        sad_16x8 = T264_mode_decision_inter_16x8b(t, vec_16x8, pred_16x8, part_16x8);
        if (sad_16x8 < sad_min)
        {
            p_min = pred_16x8;
            t->mb.mb_part = MB_16x8;
            t->mb.mb_part2[0] = part_16x8[0];
            t->mb.mb_part2[1] = part_16x8[1];
            sad_min = sad_16x8;
            copy_nvec(&vec_16x8[0][0], &t->mb.vec[0][0], 4, 2, 4);
            copy_nvec(&vec_16x8[0][1], &t->mb.vec[1][0], 4, 2, 4);
            copy_nvec(&vec_16x8[1][0], &t->mb.vec[0][8], 4, 2, 4);
            copy_nvec(&vec_16x8[1][1], &t->mb.vec[1][8], 4, 2, 4);
        }
    }

    if (t->param.block_size & SEARCH_8x16B)
    {
        vec_8x16[0][0].refno = vec_16x16[0][0].refno;
        sad_8x16 = T264_mode_decision_inter_8x16b(t, vec_8x16, pred_8x16, part_8x16);
        if (sad_8x16 < sad_min)
        {
            p_min = pred_8x16;
            t->mb.mb_part = MB_8x16;
            t->mb.mb_part2[0] = part_8x16[0];
            t->mb.mb_part2[1] = part_8x16[1];
            sad_min = sad_8x16;
            copy_nvec(&vec_8x16[0][0], &t->mb.vec[0][0], 2, 4, 4);
            copy_nvec(&vec_8x16[0][1], &t->mb.vec[1][0], 2, 4, 4);
            copy_nvec(&vec_8x16[1][0], &t->mb.vec[0][2], 2, 4, 4);
            copy_nvec(&vec_8x16[1][1], &t->mb.vec[1][2], 2, 4, 4);
        }
    }

    if (t->param.block_size & SEARCH_8x8B)
    {
        sad = 0;
        for(i = 0 ; i < 4 ; i ++)
        {
			vec_8x8[i][0].refno = vec_16x16[0][0].refno;
            sad += T264_mode_decision_inter_8x8b(t, i, vec_8x8[i], pred_8x8, &sub_part[i]);
            t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[0] =
            t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[0] =
            t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[0] =
            t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[0] = vec_8x8[i][0];

            t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 0].vec[1] =
            t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 1].vec[1] =
            t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 8].vec[1] =
            t->mb.vec_ref[VEC_LUMA + i / 2 * 16 + i % 2 * 2 + 9].vec[1] = vec_8x8[i][1];
        }

        if (sad < sad_min)
        {
            sad_min = sad;
            t->mb.mb_part = MB_8x8;
            p_min = pred_8x8;

            t->mb.submb_part[0] = sub_part[0];
            t->mb.submb_part[luma_index[4]] = sub_part[1];
            t->mb.submb_part[luma_index[8]] = sub_part[2];
            t->mb.submb_part[luma_index[12]] = sub_part[3];

            t->mb.vec[0][0] =
            t->mb.vec[0][1] = 
            t->mb.vec[0][4] = 
            t->mb.vec[0][5] = vec_8x8[0][0];
            t->mb.vec[1][0] =
            t->mb.vec[1][1] = 
            t->mb.vec[1][4] = 
            t->mb.vec[1][5] = vec_8x8[0][1];

            t->mb.vec[0][2] =
            t->mb.vec[0][3] = 
            t->mb.vec[0][6] = 
            t->mb.vec[0][7] = vec_8x8[1][0];
            t->mb.vec[1][2] =
            t->mb.vec[1][3] = 
            t->mb.vec[1][6] = 
            t->mb.vec[1][7] = vec_8x8[1][1];

            t->mb.vec[0][8] =
            t->mb.vec[0][9] = 
            t->mb.vec[0][12] = 
            t->mb.vec[0][13] = vec_8x8[2][0];
            t->mb.vec[1][8] =
            t->mb.vec[1][9] = 
            t->mb.vec[1][12] = 
            t->mb.vec[1][13] = vec_8x8[2][1];

            t->mb.vec[0][10] =
            t->mb.vec[0][11] = 
            t->mb.vec[0][14] = 
            t->mb.vec[0][15] = vec_8x8[3][0];
            t->mb.vec[1][10] =
            t->mb.vec[1][11] = 
            t->mb.vec[1][14] = 
            t->mb.vec[1][15] = vec_8x8[3][1];
        }
    }

	t->mb.is_copy = 0;
    sad_16x16 = T264_mode_decision_inter_direct_16x16b(t, vec_4x4, pred_p16x16, &part);
	if(sad_16x16 < sad_min)
	{
		for(i = 0;i < 2; ++i)
			for(j = 0;j < 16; ++j)
				t->mb.vec[i][j] = vec_4x4[i][j];
		p_min = pred_p16x16;
		t->mb.is_copy = 1;
		t->mb.mb_part = MB_16x16;
		t->mb.mb_part2[0] = part;	//part;
		sad_min = sad_16x16;
	}
    if (t->flags & USE_INTRAININTER)
        sad = T264_mode_decision_intra_y(t);
    else
        sad = -1;

    if (sad <= sad_min)
    {
		t->mb.is_copy = 0;
        sad_min = sad;
    }
    else
    {
        t->mb.mb_mode = B_MODE;
        if (p_min != t->mb.pred_p16x16)
            memcpy(t->mb.pred_p16x16, p_min, 16 * 16 * sizeof(uint8_t));
/*        if (t->mb.mb_part == MB_16x16)
            t->mb.is_copy = T264_detect_direct_16x16(t);*/
    }

    t->mb.sad = sad_min;

    return t->mb.sad;
}

#define MINPOSITIVE(x, y) (x >= 0 && y >= 0) ? T264_MIN(x, y) : T264_MAX(x, y)
static int32_t __inline
T264_get_ref_idx(T264_t* t, int32_t list)
{
    int32_t ref_idx;
    T264_vector_t vec[3];

    vec[0] = t->mb.vec_ref[VEC_LUMA - 1].vec[list];
    vec[1] = t->mb.vec_ref[VEC_LUMA - 8].vec[list];
    vec[2] = t->mb.vec_ref[VEC_LUMA - 4].vec[list];
    if (vec[2].refno == -2)
    {
        vec[2] = t->mb.vec_ref[VEC_LUMA - 8 - 1].vec[list];
    }

    ref_idx = MINPOSITIVE(vec[1].refno, vec[2].refno);
    ref_idx = MINPOSITIVE(vec[0].refno, ref_idx);

    return ref_idx;
}
#undef MINPOSITIVE

static void __inline
T264_try_get_col_zero_mv(T264_t* t, T264_vector_t vec_direct[2][16], int32_t refl0, int32_t refl1)
{
    int32_t i;
    T264_mb_context_t* mb_n = &t->ref[1][0]->mb[t->mb.mb_xy];

	if(refl0 == 0 || refl1 == 0)
    for (i = 0 ; i < 4 * 4 ; i ++)
    {
        if (((mb_n->vec[0][i].refno == 0) && 
            ABS(mb_n->vec[0][i].x) <= 1 &&
            ABS(mb_n->vec[0][i].y) <= 1) ||
			((mb_n->vec[0][i].refno == -1) && (mb_n->vec[1][i].refno == 0) &&
            ABS(mb_n->vec[1][i].x) <= 1 && ABS(mb_n->vec[1][i].y) <= 1))
        {
            if (refl0 == 0)
            {
                vec_direct[0][i].refno = 0;
                vec_direct[0][i].x = 0;
                vec_direct[0][i].y = 0;
            }
            if (refl1 == 0)
            {
                vec_direct[1][i].refno = 0;
                vec_direct[1][i].x = 0;
                vec_direct[1][i].y = 0;
            }
        }
    }
}

void
T264_get_direct_mv(T264_t* t, T264_vector_t vec_direct[2][16])
{
    int32_t refl0, refl1;
    uint8_t mb_part;

    if (t->param.direct_flag)
    {
        // l0
        refl0 = T264_get_ref_idx(t, 0);
        refl1 = T264_get_ref_idx(t, 1);

        // directZeroPredictionFlag = 1
        if (refl0 < 0 && refl1 < 0)
        {
			int	i,j;
            //memset(vec_direct, 0, sizeof(vec_direct));
			for(i = 0;i < 2;++i)
				for(j = 0;j < 16; ++j)
				{
					vec_direct[i][j].refno = 0;
						vec_direct[i][j].x = 0;
							vec_direct[i][j].y = 0;
				}
            return;
        }

	    mb_part = t->mb.mb_part;	//save old
	    t->mb.mb_part = MB_16x16;

        if (refl0 < 0)
        {
            vec_direct[0][0].refno = refl0;
            vec_direct[0][0].x = vec_direct[0][0].y = 0;
            copy_nvec(&vec_direct[0][0], &vec_direct[0][0], 4, 4, 4);
        }
        else
        {
            // when refl0 > 0 use T264_predict_mv
            T264_vector_t vec;

            vec.refno = refl0;
            T264_predict_mv(t, 0, 0, 4, &vec); 
            copy_nvec(&vec, &vec_direct[0][0], 4, 4, 4);
        }

        if (refl1 < 0)
        {
            vec_direct[1][0].refno = refl1;
            vec_direct[1][0].x = vec_direct[1][0].y = 0;
            copy_nvec(&vec_direct[1][0], &vec_direct[1][0], 4, 4, 4);
        }
        else
        {
            T264_vector_t vec;

⌨️ 快捷键说明

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