📄 block.c
字号:
/*****************************************************************************
*
* T264 AVC CODEC
*
* Copyright(C) 2004-2005 llcc <lcgate1@yahoo.com.cn>
* 2004-2005 visionany <visionany@yahoo.com.cn>
* 2005.2.24 CloudWu<sywu@sohu.com> added support for B-frame MB16x16 support
* 2005.3.2 CloudWu<sywu@sohu.com> added support for B-frame MB16x8 and MB8x16,MB8x8 support
*
* 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 "stdio.h"
#include "T264.h"
#include "utility.h"
#ifndef CHIP_DM642
#include "memory.h"
#endif
#include "assert.h"
#include "block.h"
/* intra */
static void __inline
T264dec_mb_decode_predict_i16x16_y(T264_t* t, uint8_t mode, uint8_t* pred, uint8_t* src)
{
DECLARE_ALIGNED_MATRIX(topcache, 1, 16 + CACHE_SIZE, uint8_t, CACHE_SIZE);
DECLARE_ALIGNED_MATRIX(leftcache, 1, 16 + CACHE_SIZE, uint8_t, CACHE_SIZE);
uint8_t* p;
int32_t i;
uint8_t* top, *left;
top = &topcache[CACHE_SIZE];
left = &leftcache[CACHE_SIZE];
if (mode == Intra_16x16_DC)
{
if ((t->mb.mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
{
mode = Intra_16x16_DC;
p = src - t->edged_stride;
for(i = 0 ; i < 16 ; i ++)
{
top[i] = p[i];
}
p = src - 1;
for(i = 0 ; i < 16 ; i ++)
{
left[i] = p[0];
p += t->edged_stride;
}
}
else if(t->mb.mb_neighbour & MB_LEFT)
{
mode = Intra_16x16_DCLEFT;
p = src - 1;
for(i = 0 ; i < 16 ; i ++)
{
left[i] = p[0];
p += t->edged_stride;
}
}
else if(t->mb.mb_neighbour & MB_TOP)
{
mode = Intra_16x16_DCTOP;
p = src - t->edged_stride;
for(i = 0 ; i < 16 ; i ++)
{
top[i] = p[i];
}
}
else
{
mode = Intra_16x16_DC128;
}
}
else
{
switch(mode)
{
case Intra_16x16_TOP:
p = src - t->edged_stride;
for(i = 0 ; i < 16 ; i ++)
{
top[i] = p[i];
}
break;
case Intra_16x16_LEFT:
p = src - 1;
for(i = 0 ; i < 16 ; i ++)
{
left[i] = p[0];
p += t->edged_stride;
}
break;
case Intra_16x16_PLANE:
p = src - t->edged_stride;
for(i = -1 ; i < 16 ; i ++)
{
top[i] = p[i];
}
p -= 1;
for(i = -1 ; i < 16 ; i ++)
{
left[i] = p[0];
p += t->edged_stride;
}
break;
default:
assert(0);
break;
}
}
t->pred16x16[mode](pred, 16, top, left);
}
static void __inline
T264dec_mb_decode_predict_i4x4_y(T264_t* t, uint8_t idx, uint8_t mode, uint8_t* pred, uint8_t* src)
{
DECLARE_ALIGNED_MATRIX(topcache, 8 + CACHE_SIZE, 1, uint8_t, CACHE_SIZE);
DECLARE_ALIGNED_MATRIX(leftcache, 4 + CACHE_SIZE, 1, uint8_t, CACHE_SIZE);
static const int32_t neighbour[] =
{
0, MB_LEFT, MB_LEFT, MB_LEFT,
MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP, MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,
MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP| MB_TOPRIGHT, MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP,
MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP, MB_LEFT |MB_TOP| MB_TOPRIGHT, MB_LEFT| MB_TOP
};
static const int32_t fix[] =
{
~0, ~0, ~0, ~0,
~0, ~MB_TOPRIGHT, ~0, ~MB_TOPRIGHT,
~0, ~0, ~0, ~MB_TOPRIGHT,
~0, ~MB_TOPRIGHT, ~0, ~MB_TOPRIGHT
};
uint8_t* p;
int32_t i;
uint8_t* top = &topcache[CACHE_SIZE];
uint8_t* left = &leftcache[CACHE_SIZE];
if (mode == Intra_4x4_DC)
{
int32_t mb_neighbour = (t->mb.mb_neighbour| neighbour[idx]) & fix[idx];
if ((mb_neighbour & (MB_LEFT | MB_TOP)) == (MB_LEFT | MB_TOP))
{
mode = Intra_4x4_DC;
p = src - t->edged_stride;
for(i = 0 ; i < 4 ; i ++)
{
top[i] = p[i];
}
p = src - 1;
for(i = 0 ; i < 4 ; i ++)
{
left[i] = p[0];
p += t->edged_stride;
}
}
else if(mb_neighbour & MB_LEFT)
{
mode = Intra_4x4_DCLEFT;
p = src - 1;
for(i = 0 ; i < 4 ; i ++)
{
left[i] = p[0];
p += t->edged_stride;
}
}
else if(mb_neighbour & MB_TOP)
{
mode = Intra_4x4_DCTOP;
p = src - t->edged_stride;
for(i = 0 ; i < 4 ; i ++)
{
top[i] = p[i];
}
}
else
{
mode = Intra_4x4_DC128;
}
}
else
{
switch(mode)
{
case Intra_4x4_TOP:
p = src - t->edged_stride;
for(i = 0 ; i < 4 ; i ++)
{
top[i] = p[i];
}
break;
case Intra_4x4_LEFT:
case Intra_4x4_HORIZONTAL_UP:
p = src - 1;
for(i = 0 ; i < 4 ; i ++)
{
left[i] = p[0];
p += t->edged_stride;
}
break;
case Intra_4x4_DIAGONAL_DOWNLEFT:
case Intra_4x4_VERTICAL_LEFT:
{
int32_t mb_neighbour = (t->mb.mb_neighbour| neighbour[idx]) & fix[idx];
p = src - t->edged_stride;
if((idx & 3) == 3 && t->mb.mb_x == t->mb_width - 1) //if is the right-most sub-block, if is th last MB in horizontal, no top-right exist
mb_neighbour &= ~MB_TOPRIGHT;
if (mb_neighbour & MB_TOPRIGHT)
{
for(i = 0 ; i < 8 ; i ++)
{
top[i] = p[i];
}
}
else
{
for(i = 0 ; i < 4 ; i ++)
{
top[i] = p[i];
}
top[4] = p[3];
top[5] = p[3];
top[6] = p[3];
top[7] = p[3];
}
}
break;
case Intra_4x4_DIAGONAL_DOWNRIGHT:
case Intra_4x4_VERTICAL_RIGHT:
case Intra_4x4_HORIZONTAL_DOWN:
p = src - t->edged_stride;
for(i = -1 ; i < 4 ; i ++)
{
top[i] = p[i];
}
p -= 1;
for(i = -1 ; i < 4 ; i ++)
{
left[i] = p[0];
p += t->edged_stride;
}
break;
default:
assert(0);
break;
}
}
t->pred4x4[mode](pred, 4, top, left);
}
static void __inline
T264dec_mb_decode_predict_i8x8_y(T264_t* t, uint8_t mode, uint8_t* pred_u, uint8_t* pred_v)
{
DECLARE_ALIGNED_MATRIX(topcacheu, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
DECLARE_ALIGNED_MATRIX(leftcacheu, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
DECLARE_ALIGNED_MATRIX(topcachev, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
DECLARE_ALIGNED_MATRIX(leftcachev, 1, 8 + CACHE_SIZE, uint8_t, CACHE_SIZE);
uint8_t* p_u, *p_v;
int32_t i;
uint8_t* top_u, *left_u;
uint8_t* top_v, *left_v;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -