📄 softidct.cpp
字号:
IncPtr(true, true);
//V
CopyBlock8x8(ref_ptr, curr_block_ptr, current_pitch, current_pitch);
}
//----------------------------
static void FillEdge(byte *ptr, int sx, int sy, int EdgeX, int EdgeY){
int n;
byte *p;
int InnerWidth = sx - EdgeX*2;
int InnerHeight = sy - EdgeY*2;
//left and right
p = ptr + EdgeX + EdgeY * sx;
for(n=0;n<InnerHeight;++n) {
MemSet(p-EdgeX, p[0], EdgeX);
MemSet(p+InnerWidth,p[InnerWidth-1], EdgeX);
p += sx;
}
//top
p = ptr;
for (n=0;n<EdgeY;++n) {
MemCpy(p, ptr+EdgeY * sx, sx);
p += sx;
}
//bottom
p = ptr + (sy-EdgeY)*sx;
for (n=0;n<EdgeY;++n) {
MemCpy(p, ptr+(sy-EdgeY-1)*sx, sx);
p += sx;
}
}
//----------------------------
void C_softidct::FillEdgeYUV(byte *ptr){
//Y
FillEdge(ptr, buffer_sx, buffer_sy, EDGE, EDGE);
//U
ptr += Y_buffer_size;
FillEdge(ptr, buffer_sx>>UVX2, buffer_sy>>UVY2, EDGE>>UVX2, EDGE>>UVY2);
//V
ptr += Y_buffer_size >> (UVX2+UVY2);
FillEdge(ptr, buffer_sx>>UVX2, buffer_sy>>UVY2, EDGE>>UVX2, EDGE>>UVY2);
}
//----------------------------
bool C_softidct::SetBufferCount(int n){
if(n<=bufer_count)
return true;
int i;
if(n>MAXBUF){
return false;
}
for(i=n; i<bufer_count; ++i){
delete[] buffers[i].allocated;
buffers[i].allocated = NULL;
}
if(bufer_count > n)
bufer_count = n;
for(i=bufer_count; i<n; ++i){
int Align = 32;
buffers[i].allocated = new byte[buffer_size + Align];
if(!buffers[i].allocated)
break;
/*
if(i>=2 && AvailMemory()<64*1024){
delete[] buffers[i].allocated;
buffer_size = NULL;
max_buffer_count = bufer_count;
break;
}
*/
buffers[i].ptr = (byte*)(((dword)buffers[i].allocated + Align-1) & ~(Align-1));
buffers[i].has_border = false;
buffers[i].frame_index = -1;
bufer_count = i+1;
#ifdef _DEBUG
if(i==2) //fill B-frame buffer to green, for easier detection of problems
MemSet(buffers[i].ptr, 0x0, buffer_size);
#endif
}
if(rendered_buffer_index >= bufer_count)
rendered_buffer_index = -1;
return (bufer_count == n);
}
//----------------------------
void C_softidct::FrameStart(int frame_index, int DstNo, int BackNo, int FwdNo, int ShowNo){
rendered_buffer_index = ShowNo;
last_frame_index = buffers[DstNo].frame_index;// = -1;
buffers[DstNo].frame_index = frame_index;
curr_frame_buffer_ptr = buffers[DstNo].ptr;
ptr_backward_buffer = NULL;
ptr_forward_buffer = NULL;
ptr_b_max = NULL;
ptr_f_max = NULL;
if(BackNo>=0){
ptr_backward_buffer = buffers[BackNo].ptr;
if(!buffers[BackNo].has_border){
buffers[BackNo].has_border = true;
FillEdgeYUV(ptr_backward_buffer);
}
ptr_b_max = ptr_backward_buffer + buffer_size -8-8*UV_buffer_pitch;
}
if(FwdNo>=0){
ptr_forward_buffer = buffers[FwdNo].ptr;
if(!buffers[FwdNo].has_border){
buffers[FwdNo].has_border = true;
FillEdgeYUV(ptr_forward_buffer);
}
ptr_f_max = ptr_forward_buffer + buffer_size -8-8*UV_buffer_pitch;
}
//invalidate border for dst
buffers[DstNo].has_border = false;
}
//----------------------------
C_softidct::C_softidct(dword sx, dword sy):
bufer_count(0),
buffer_size(0),
#ifdef ARM
dyn_code(NULL),
#endif
image_sx(sx),
image_sy(sy),
rendered_buffer_index(-1),
last_frame_index(-1)
{
MemSet(buffers, 0, sizeof(buffers));
IDCT_Const8x8 = ::IDCT_Const8x8;
#ifdef ARM
#ifdef USE_WMMX
dword cpu_caps = C_dyn_code::GetCpuCaps();
bool use_wmmx = (cpu_caps & C_dyn_code::CPU_WIRELESS_MMX);
#else
bool use_wmmx = false;
#endif
dyn_code = C_dyn_code::Create();
void BuildMotionCompensationFunctions(C_dyn_code&, bool use_wmmx);
BuildMotionCompensationFunctions(*dyn_code, use_wmmx);
void BuildIDCTFunctions(C_dyn_code&, bool use_wmmx);
BuildIDCTFunctions(*dyn_code, use_wmmx);
dyn_code->CodeBuild();
//if(((dword*)dyn_code->Code(0))[-1]!=0xe289409d) Fatal("!", 0);
int i;
for(i=0; i<4; i++)
add_block[i] = (t_AddBlock)dyn_code->Code(i);
all_copy_block[0][0] = all_copy_block[1][0] = (t_CopyBlock)dyn_code->Code(4);
for(i=0; i<3; i++){
all_copy_block[0][1+i] = (t_CopyBlock)dyn_code->Code(5+i*2);
all_copy_block[1][1+i] = (t_CopyBlock)dyn_code->Code(6+i*2);
}
CopyBlock8x8 = (t_CopyBlock)dyn_code->Code(11);
CopyBlock16x16 = (t_CopyBlock)dyn_code->Code(12);
IDCT_Block4x8 = (t_IDCT_Block)dyn_code->Code(13);
IDCT_Block8x8 = (t_IDCT_Block)dyn_code->Code(14);
if(use_wmmx)
IDCT_Const8x8 = (t_IDCT_Const8x8)dyn_code->Code(15);
#else
add_block[0] = AddBlock;
add_block[1] = AddBlockHor;
add_block[2] = AddBlockVer;
add_block[3] = AddBlockHorVer;
all_copy_block[0][0] = ::CopyBlock;
all_copy_block[1][0] = ::CopyBlock;
all_copy_block[0][1] = ::CopyBlockHor;
all_copy_block[1][1] = ::CopyBlockHorRound;
all_copy_block[0][2] = ::CopyBlockVer;
all_copy_block[1][2] = ::CopyBlockVerRound;
all_copy_block[0][3] = ::CopyBlockHorVer;
all_copy_block[1][3] = ::CopyBlockHorVerRound;
CopyBlock8x8 = ::CopyBlock8x8;
CopyBlock16x16 = ::CopyBlock16x16;
IDCT_Block4x8 = ::IDCT_Block4x8;
IDCT_Block8x8 = ::IDCT_Block8x8;
#endif
temp_buffer_16 = (byte*)(((dword)_temp_buffer + 15) & ~15);
//compute sizes of buffers
const int AlignX = (8 << UVX2) - 1;
const int AlignY = (8 << UVY2) - 1;
buffer_sx = ((image_sx+AlignX)&~AlignX)+2*EDGE;
buffer_sy = ((image_sy+AlignY)&~AlignY)+2*EDGE;
Y_buffer_size = buffer_sy * buffer_sx;
buffer_size = Y_buffer_size + 2*(Y_buffer_size >> (UVX2+UVY2));
UV_buffer_pitch = buffer_sx >> UVX2;
pass_offset[0] = 8; //Y[0;0] -> Y[0;1]
pass_offset[1] = 8*buffer_sx-8; //Y[0;1] -> Y[1;0]
pass_offset[2] = 8; //Y[1;0] -> Y[1;1]
pass_offset[4] = Y_buffer_size >> 2; //U->V
pass_offset[5] = 0;
SetRounding(false);
}
//----------------------------
C_softidct::~C_softidct(){
for(int i=0; i<bufer_count; ++i)
delete[] buffers[i].allocated;
#ifdef ARM
delete dyn_code;
#endif
}
//----------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -