?? encoder.c
字號:
pCodec->DMA_COMMAND_local[39] = (uint32_t) 0x4B00010; // enable Transfer Done flag mask
// Enable DMA start transferring
// Enable chain transfer
// From sequential System memory to sequential Local memory
// transfer 0x10 words (64 bytes)
#endif
POLL_MARKER_S
while((pmdma->Status & 0x1) == 0);
POLL_MARKER_E
#if defined(CORE_VERSION_1)
// begin to move the local DMA commands (from 12th to 12+16-1=27th)
// to the system memory and start DMA procedure..
DMA_MOVE(12, 0x4B00010) // enable Transfer Done flag mask
// Enable DMA start transferring
// Enable chain transfer
// From sequential Local memory to sequential System memory
// transfer 0x10(16) words
#elif defined(CORE_VERSION_2)
// begin to move the local DMA commands (from 12th to 12+28-1=39th)
// to the system memory and start DMA procedure..
DMA_MOVE(12, 0x4B0001C) // enable Transfer Done flag mask
#endif
READ_ASADR(*pBits) // 64 byte
// read Bit-Stream Access Length Register (0x10050)
READ_BALR(x) // compressed data in local memory (words)
// read VLC/VLD Data Address Register (0x10044)
READ_VOADR(y) // compressed data in local memory (bits)
// the following lines... why???
x = (x & 0x3c);
y = y & 0xff;
bit_header = y + x*8; // total bits in local memory
pEnc->iFrameNum = 0;
pEnc->current1->coding_type = I_VOP;
if (!pEnc->mbParam.h263) {
pEnc->mbParam.m_rounding_type = 1;
pEnc->current1->rounding_type = pEnc->mbParam.m_rounding_type;
BitstreamWriteVolHeader(&pEnc->mbParam, pEnc->current1,pEnc->pCodec);
BitstreamWriteVopHeader(&pEnc->mbParam, pEnc->current1, 1,pEnc->pCodec);
} else {
pEnc->mbParam.m_rounding_type = 0;
pEnc->current1->rounding_type = pEnc->mbParam.m_rounding_type;
BitstreamWriteShortHeader(&pEnc->mbParam, pEnc->current1, 0,pEnc->pCodec);
}
// even_odd_1 was used to control the selection bewteen
// (CUR_Y0 ,CUR_U0,CUR_V0) buffer and (CUR_Y1,CUR_U1,CUR_V1) buffer
pCodec->even_odd_1 = 0;
// even_odd_I was used to control the selection bewteen
// LOCAL_PREDICTOR0 's double buffers
pCodec->even_odd_I = 0;
// DZQAR is a constant value = 0x8000800
// DZAR/QAR register is at 0x10038
// It was used to set the Quantization Block Address to 0x0800
SET_QAR(DZQAR)
// set ACDC Predictor Buffer Address
// ACDCPAR register is at 0x10040
SET_ACDCPAR(LOCAL_PREDICTOR0)
POLL_MARKER_S
while((pmdma->Status & 0x1) == 0);
POLL_MARKER_E
pCodec->DMA_COMMAND_local[23] = (uint32_t) 0x800010; // disable Transfer Done flag mask
// Enable DMA start transferring
// Disable chain transfer
// From sequential System memory to sequential Local memory
// transfer 0x10(16) words = 64 bytes
pCodec->DMA_COMMAND_local[27] = (uint32_t) 0x4A40010; // Enable Transfer Done flag mask
// Enable DMA start transferring
// Enable chain transfer
// From sequential System memory to 2D Local memory
// transfer 0x10(16) words
pMB = pEnc->current1->mbs;
for (y = 0; y < pEnc->mbParam.mb_height; y++) {
MOVE_DEFAULT_PREDICTOR(&pEnc->mbParam,y,pCodec);
for (x = 0; x < pEnc->mbParam.mb_width; x++) {
// CodeIntraMB() was just used to set the quantization level for each marcoblock
CodeIntraMB(pEnc, pMB);
RTL_DEBUG_OUT(0x91000000 | y << 12 | x)
MBTransQuantIntra(&pEnc->mbParam, pEnc->current1, pMB, x, y, pEnc->mbParam.mb_width,pCodec);
RTL_DEBUG_OUT(0x92000000 | y << 12 | x)
pMB++;
if (pEnc->mbParam.resyn==1)
{
pCodec->acdc_status = 6; // make Diagonal and Top default predictor
}
}
if (pEnc->mbParam.resyn==1)
{
if (!pEnc->mbParam.h263)
{
if (y!= (pEnc->mbParam.mb_height-1))
{
pMB->quant = pEnc->current1->quant;
BitstreamPadAlways(pCodec);
BitstreamPutBits(VIDO_RESYN_MARKER, 17,pCodec);
BitstreamPutBits(x + y*pEnc->mbParam.mb_width, log2bin(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height - 1),pCodec);
BitstreamPutBits(pMB->quant, 5,pCodec);
BitstreamPutBit(0,pCodec);
}
}
else
{
if (y!= (pEnc->mbParam.mb_height-1))
{
#if defined(CORE_VERSION_2)
// In core_version_1 ,the hardware register (CPSTS) did not provide the
// bit to check whether the VLC engine is done or not. Without the bit,
// potentially, the follwing codes in core_version_1 will cause bitstream
// buffer contention if we want to insert the resync marker to bitstream
// buffer while VLC engine is not done and still accessing the same
// bitstream buffer at the same time. Therefore, core_vesion_2 hardware has
// provided another bit on bit15 of CPSTS register to let software check
// the VLC done status in order to avoid bitstream buffer contention.
// check whether the VLC is done or not
// CPSTS register is at address 0x10028
int32_t cpsts;
do {
READ_CPSTS(cpsts)
} while (!(cpsts&0x08000));
#endif
pMB->quant = pEnc->current1->quant;
BitstreamPutBits(VIDO_RESYN_MARKER, 17,pCodec);
BitstreamPutBits(y+1, 5,pCodec);
BitstreamPutBits(0, 2,pCodec); // ID
BitstreamPutBits(pMB->quant, 5,pCodec);
}
}
}
}
BitstreamPadAlways(pCodec);
// check autobuffer done
do {
READ_VLDSTS(y)
} while(!(y&0x0400));
READ_ASADR(data_64b) // 64 byte
READ_BALR(x) // compressed data in local memory (words)
READ_VOADR(y) // compressed data in local memory (bits)
x = (x & 0x3c);
y = y & 0xff;
y = y + x*8; // total bits in local memory
data_64b = data_64b - *pBits; // total bytes in system memory
*pBits = y + data_64b * 8 - bit_header;
pEnc->mbParam.m_fcode = 1;
#ifdef DUMP_RECONSTRUCTED_RESULT
dump_reconstructed_image_to_file(pEnc->current1->reconstruct.y,pEnc->mbParam.width,pEnc->mbParam.height,1,reconstructed_result_file);
dump_reconstructed_image_to_file(pEnc->current1->reconstruct.u,pEnc->mbParam.width/2,pEnc->mbParam.height/2,0,reconstructed_result_file);
dump_reconstructed_image_to_file(pEnc->current1->reconstruct.v,pEnc->mbParam.width/2,pEnc->mbParam.height/2,0,reconstructed_result_file);
#endif
return 1; // intra
}
int
encoder_encode(Encoder * pEnc, Faraday_ENC_FRAME * pFrame)
{
FTMCP100_CODEC *pCodec=(FTMCP100_CODEC *)pEnc->pCodec;
Bitstream bs;
uint32_t bits;
uint16_t write_vol_header = 0;
char not_coded_flag=1;
DECLARE_MP4_PTR
#if (defined(DUMP_ME_RESULT) || defined(DUMP_PMV_RESULT))
static int framenr=0;
#endif
#ifdef DUMP_ME_RESULT
fprintf(me_result_file,"Frame %d:\n",framenr);
#endif
#ifdef DUMP_PMV_RESULT
fprintf(pmv_result_file,"Frame %d:\n",framenr);
#endif
#if (defined(DUMP_ME_RESULT) || defined(DUMP_PMV_RESULT))
framenr++;
#endif
if (pEnc->reference->image.y != NULL)
{
SWAP(pEnc->current1, pEnc->reference);
not_coded_flag=0;
}
pEnc->current1->global_flags = pFrame->general;
pEnc->current1->motion_flags = pFrame->motion;
pEnc->current1->seconds = pEnc->mbParam.m_seconds;
pEnc->current1->ticks = pEnc->mbParam.m_ticks;
BitstreamInit(&bs, pFrame->bitstream, 0);
if (pFrame->quant == 0) {
pEnc->current1->quant = pEnc->rate_control.rtn_quant;
} else {
pEnc->current1->quant = pFrame->quant;
}
RTL_DEBUG_OUT(0x94000000 | (pEnc->current1->quant))
if (pEnc->current1->global_flags & Faraday_H263QUANT) {
if (pEnc->mbParam.m_quant_type != H263_QUANT)
write_vol_header = 1;
pEnc->mbParam.m_quant_type = H263_QUANT;
} else if (pEnc->current1->global_flags & Faraday_MPEGQUANT) {
int matrix1_changed, matrix2_changed;
matrix1_changed = matrix2_changed = 0;
if (pEnc->mbParam.m_quant_type != MPEG4_QUANT)
write_vol_header = 1;
pEnc->mbParam.m_quant_type = MPEG4_QUANT;
if ((pEnc->current1->global_flags & Faraday_CUSTOM_QMATRIX) > 0) {
if (pFrame->quant_intra_matrix != NULL)
matrix1_changed = set_intra_matrix(pFrame->quant_intra_matrix,pEnc->pCodec);
if (pFrame->quant_inter_matrix != NULL)
matrix2_changed = set_inter_matrix(pFrame->quant_inter_matrix,pEnc->pCodec);
} else {
matrix1_changed = set_intra_matrix(get_default_intra_matrix(),pEnc->pCodec);
matrix2_changed = set_inter_matrix(get_default_inter_matrix(),pEnc->pCodec);
}
if (write_vol_header == 0)
write_vol_header = matrix1_changed | matrix2_changed;
}
//if (pEnc->current1->image.y == NULL) /// not coded
if(not_coded_flag)
{
FrameCodePNotCoded(pEnc, &bs, &bits, write_vol_header);
}
else
{
if (pFrame->intra < 0) {
if ((pEnc->iFrameNum == 0) || ((pEnc->iMaxKeyInterval > 0)
&& (pEnc->iFrameNum >= pEnc->iMaxKeyInterval))) {
pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
} else {
pFrame->intra = FrameCodeP(pEnc, &bs, &bits, write_vol_header);
}
} else {
if (pFrame->intra == 1) {
pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
} else {
pFrame->intra = FrameCodeP(pEnc, &bs, &bits, write_vol_header);
}
}
}
#if defined(RTL_PLATFORM)
// why should we do this for RTL platform???
// well, because the result of legnth is not right if we use FPGA platform's approach to
// calculate the frame length... so we copy the following line from well-established
// codes for RTL platform from Rogers... this approach was approved before by Rogers
pFrame->length = (bits>>3) + ((bits&0x7) != 0);
#elif defined(FPGA_PLATFORM)
// wait for auto buffer clean
{
unsigned int data_64b;
unsigned int bit_len;
unsigned int y;
// check autobuffer done
do {
READ_VLDSTS(y)
} while(!(y&0x0400 ));
READ_ASADR(data_64b);
READ_BALR(bit_len);
bit_len = bit_len & 0x3c; // access local memory position
data_64b = data_64b + bit_len - (unsigned int)bs.start;
READ_VOADR(bits);
bits &= 0x1f; /// got last bit
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -