📄 inter_b.c
字号:
/*****************************************************************************
*
* 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 + -