📄 dct_encode.c
字号:
}
}else{
/* Else there was NO zero run. */
/* Tokenise the value */
token_count += TokenizeDctValue( RawData[i],
&TokenListPtr[token_count] );
}
}
}
/* Return the total number of tokens (including additional bits
tokens) used. */
return token_count;
}
ogg_uint32_t DPCMTokenizeBlock (CP_INSTANCE *cpi,
ogg_int32_t FragIndex){
ogg_uint32_t token_count;
if ( GetFrameType(&cpi->pb) == KEY_FRAME ){
/* Key frame so code block in INTRA mode. */
cpi->pb.CodingMode = CODE_INTRA;
}else{
/* Get Motion vector and mode for this block. */
cpi->pb.CodingMode = cpi->pb.FragCodingMethod[FragIndex];
}
/* Tokenise the dct data. */
token_count = TokenizeDctBlock( cpi->pb.QFragData[FragIndex],
cpi->pb.TokenList[FragIndex] );
cpi->FragTokenCounts[FragIndex] = token_count;
cpi->TotTokenCount += token_count;
/* Return number of pixels coded (i.e. 8x8). */
return BLOCK_SIZE;
}
static int AllZeroDctData( Q_LIST_ENTRY * QuantList ){
ogg_uint32_t i;
for ( i = 0; i < 64; i ++ )
if ( QuantList[i] != 0 )
return 0;
return 1;
}
static void MotionBlockDifference (CP_INSTANCE * cpi, unsigned char * FiltPtr,
ogg_int16_t *DctInputPtr, ogg_int32_t MvDevisor,
unsigned char* old_ptr1, unsigned char* new_ptr1,
ogg_uint32_t FragIndex,ogg_uint32_t PixelsPerLine,
ogg_uint32_t ReconPixelsPerLine) {
ogg_int32_t MvShift;
ogg_int32_t MvModMask;
ogg_int32_t AbsRefOffset;
ogg_int32_t AbsXOffset;
ogg_int32_t AbsYOffset;
ogg_int32_t MVOffset; /* Baseline motion vector offset */
ogg_int32_t ReconPtr2Offset; /* Offset for second reconstruction in
half pixel MC */
unsigned char *ReconPtr1; /* DCT reconstructed image pointers */
unsigned char *ReconPtr2; /* Pointer used in half pixel MC */
switch(MvDevisor) {
case 2:
MvShift = 1;
MvModMask = 1;
break;
case 4:
MvShift = 2;
MvModMask = 3;
break;
default:
break;
}
cpi->MVector.x = cpi->pb.FragMVect[FragIndex].x;
cpi->MVector.y = cpi->pb.FragMVect[FragIndex].y;
/* Set up the baseline offset for the motion vector. */
MVOffset = ((cpi->MVector.y / MvDevisor) * ReconPixelsPerLine) +
(cpi->MVector.x / MvDevisor);
/* Work out the offset of the second reference position for 1/2
pixel interpolation. For the U and V planes the MV specifies 1/4
pixel accuracy. This is adjusted to 1/2 pixel as follows ( 0->0,
1/4->1/2, 1/2->1/2, 3/4->1/2 ). */
ReconPtr2Offset = 0;
AbsXOffset = cpi->MVector.x % MvDevisor;
AbsYOffset = cpi->MVector.y % MvDevisor;
if ( AbsXOffset ) {
if ( cpi->MVector.x > 0 )
ReconPtr2Offset += 1;
else
ReconPtr2Offset -= 1;
}
if ( AbsYOffset ) {
if ( cpi->MVector.y > 0 )
ReconPtr2Offset += ReconPixelsPerLine;
else
ReconPtr2Offset -= ReconPixelsPerLine;
}
if ( cpi->pb.CodingMode==CODE_GOLDEN_MV ) {
ReconPtr1 = &cpi->
pb.GoldenFrame[cpi->pb.recon_pixel_index_table[FragIndex]];
} else {
ReconPtr1 = &cpi->
pb.LastFrameRecon[cpi->pb.recon_pixel_index_table[FragIndex]];
}
ReconPtr1 += MVOffset;
ReconPtr2 = ReconPtr1 + ReconPtr2Offset;
AbsRefOffset = abs((int)(ReconPtr1 - ReconPtr2));
/* Is the MV offset exactly pixel alligned */
if ( AbsRefOffset == 0 ){
dsp_static_sub8x8( FiltPtr, ReconPtr1, DctInputPtr,
PixelsPerLine, ReconPixelsPerLine );
dsp_static_copy8x8 (new_ptr1, old_ptr1, PixelsPerLine);
} else {
/* Fractional pixel MVs. */
/* Note that we only use two pixel values even for the diagonal */
dsp_static_sub8x8avg2(FiltPtr, ReconPtr1,ReconPtr2,DctInputPtr,
PixelsPerLine, ReconPixelsPerLine);
dsp_static_copy8x8 (new_ptr1, old_ptr1, PixelsPerLine);
}
}
void TransformQuantizeBlock (CP_INSTANCE *cpi, ogg_int32_t FragIndex,
ogg_uint32_t PixelsPerLine ) {
unsigned char *new_ptr1; /* Pointers into current frame */
unsigned char *old_ptr1; /* Pointers into old frame */
unsigned char *FiltPtr; /* Pointers to srf filtered pixels */
ogg_int16_t *DctInputPtr; /* Pointer into buffer containing input to DCT */
int LeftEdge; /* Flag if block at left edge of component */
ogg_uint32_t ReconPixelsPerLine; /* Line length for recon buffers. */
unsigned char *ReconPtr1; /* DCT reconstructed image pointers */
ogg_int32_t MvDevisor; /* Defines MV resolution (2 = 1/2
pixel for Y or 4 = 1/4 for UV) */
new_ptr1 = &cpi->yuv1ptr[cpi->pb.pixel_index_table[FragIndex]];
old_ptr1 = &cpi->yuv0ptr[cpi->pb.pixel_index_table[FragIndex]];
DctInputPtr = cpi->DCTDataBuffer;
/* Set plane specific values */
if (FragIndex < (ogg_int32_t)cpi->pb.YPlaneFragments){
ReconPixelsPerLine = cpi->pb.YStride;
MvDevisor = 2; /* 1/2 pixel accuracy in Y */
}else{
ReconPixelsPerLine = cpi->pb.UVStride;
MvDevisor = 4; /* UV planes at 1/2 resolution of Y */
}
/* adjusted / filtered pointers */
FiltPtr = &cpi->ConvDestBuffer[cpi->pb.pixel_index_table[FragIndex]];
if ( GetFrameType(&cpi->pb) == KEY_FRAME ) {
/* Key frame so code block in INTRA mode. */
cpi->pb.CodingMode = CODE_INTRA;
}else{
/* Get Motion vector and mode for this block. */
cpi->pb.CodingMode = cpi->pb.FragCodingMethod[FragIndex];
}
/* Selection of Quantiser matirx and set other plane related values. */
if ( FragIndex < (ogg_int32_t)cpi->pb.YPlaneFragments ){
LeftEdge = !(FragIndex%cpi->pb.HFragments);
/* Select the approrpriate Y quantiser matrix */
if ( cpi->pb.CodingMode == CODE_INTRA )
select_Y_quantiser(&cpi->pb);
else
select_Inter_quantiser(&cpi->pb);
}else{
LeftEdge = !((FragIndex-cpi->pb.YPlaneFragments)%(cpi->pb.HFragments>>1));
/* Select the approrpriate UV quantiser matrix */
if ( cpi->pb.CodingMode == CODE_INTRA )
select_UV_quantiser(&cpi->pb);
else
select_Inter_quantiser(&cpi->pb);
}
if ( ModeUsesMC[cpi->pb.CodingMode] ){
MotionBlockDifference(cpi, FiltPtr, DctInputPtr, MvDevisor,
old_ptr1, new_ptr1, FragIndex, PixelsPerLine,
ReconPixelsPerLine);
} else if ( (cpi->pb.CodingMode==CODE_INTER_NO_MV ) ||
( cpi->pb.CodingMode==CODE_USING_GOLDEN ) ) {
if ( cpi->pb.CodingMode==CODE_INTER_NO_MV ) {
ReconPtr1 = &cpi->
pb.LastFrameRecon[cpi->pb.recon_pixel_index_table[FragIndex]];
} else {
ReconPtr1 = &cpi->
pb.GoldenFrame[cpi->pb.recon_pixel_index_table[FragIndex]];
}
dsp_static_sub8x8( FiltPtr, ReconPtr1, DctInputPtr,
PixelsPerLine, ReconPixelsPerLine );
dsp_static_copy8x8 (new_ptr1, old_ptr1, PixelsPerLine);
} else if ( cpi->pb.CodingMode==CODE_INTRA ) {
dsp_static_sub8x8_128(FiltPtr, DctInputPtr, PixelsPerLine);
dsp_static_copy8x8 (new_ptr1, old_ptr1, PixelsPerLine);
}
/* Proceed to encode the data into the encode buffer if the encoder
is enabled. */
/* Perform a 2D DCT transform on the data. */
dsp_static_fdct_short( cpi->DCTDataBuffer, cpi->DCT_codes );
/* Quantize that transform data. */
quantize ( &cpi->pb, cpi->DCT_codes, cpi->pb.QFragData[FragIndex] );
if ( (cpi->pb.CodingMode == CODE_INTER_NO_MV) &&
( AllZeroDctData(cpi->pb.QFragData[FragIndex]) ) ) {
cpi->pb.display_fragments[FragIndex] = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -