⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encoder.c

📁 基于Linux的ffmepg decoder
💻 C
📖 第 1 页 / 共 5 页
字号:

	  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
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -