📄 mp4_decodeencodeapi.c
字号:
//=============================================================
// 文件名称: MP4_DecodeEncode.c
// 功能描述: mp4编解码
// 维护记录: 2007-01-16 v1.0
//=============================================================
#include "SPCE3200_Register.h"
#include "SPCE3200_Constant.h"
#include ".\MP4_Codec\MP4_Codec.h"
#include ".\System\BLNDMA.h"
unsigned int g_unMP4HW_RunMode=NORMAL_MODE;
unsigned int g_unMP4HW_dvWidth;
unsigned int g_unMP4HW_dvHigh;
unsigned int g_unBLD_DstWidth;
unsigned int g_unBLD_DstHigh;
unsigned int g_unMP4HW_DecodeBuff[3];
unsigned int g_unMP4HW_TVBuffer[3];
unsigned int g_unMP4_encodePFrameCount;
unsigned int g_unMP4_decodePFrameCount;
unsigned int g_unMP4_setLCD_OK=0;
unsigned int g_unMP4_TVCount=0;
void mp4_SetRunMode(unsigned char m_ucMP4HW_Rmode)
{
g_unMP4HW_RunMode = m_ucMP4HW_Rmode;
g_unMP4_encodePFrameCount = 0;
g_unMP4_decodePFrameCount = 0;
g_unMP4_setLCD_OK = 0;
g_unMP4_TVCount = 0;
}
void mp4_compressor_prepare(unsigned int width,unsigned int height,unsigned int p_frame_cntr,unsigned int unVOPTimeIncLen)
{
// Rate control initial setting(videorst)
*P_MPEG4_MODE_CTRL3 = 0x08;//Mpg1skipmode
*P_MPEG4_MODE_CTRL3 = 0x00;
// imgwidth
*P_MPEG4_FRAMEBUFFER_HSIZE = 320; //original width
*P_MPEG4_WIDTH_LOW = width;
*P_MPEG4_WIDTH_HIGH = (width>>8);
// imgheight
*P_MPEG4_HEIGHT_LOW = height;
*P_MPEG4_HEIGHT_HIGH = (height>>8);
// hoffset
*P_MPEG4_HOROFFSET_LOW = 0x00;
*P_MPEG4_HOROFFSET_HIGH = 0x00;
// voffset
*P_MPEG4_VEROFFSET_LOW = 0x00;
*P_MPEG4_VEROFFSET_HIGH = 0x00;
// vlc offset
*P_MPEG4_VLCOFFSET_SALOW = 0x00;
*P_MPEG4_VLCOFFSET_SAMID = 0x00;
*P_MPEG4_VLCOFFSET_SAHIGH = 0x00;
//
*P_MPEG4_HOR_SCALE = 0x00; //add by ww
*P_MPEG4_VEL_SCALE = 0x00; //add by ww
*P_MPEG4_PFRAME_NUMBER = 2;
if(((g_unMP4_encodePFrameCount++)%(P_FRAME_NUMBER+1))!=0)
{
*P_MPEG4_FRAME_MODE=0;//always P frame
}
else
{
*P_MPEG4_FRAME_MODE=1;//always I frame
}
*P_MPEG4_MODE_CTRL3 = 0x72;//gopsetting,SOF mode,half pel en
// 0 : no truncate, 1 : truncate
*P_MPEG4_TRUNCATE_CTRL = 0x01;
// set Qscale enable
*P_MPEG4_QTABLE_CTRL = 0x06;
// turn on all the srams of texture engine
*P_MPEG4_SRAM_EN = 0x01;
// VOPTimeIncLen 20frame per sec
*P_MPEG4_VOPTIMEINC_LENGTH = unVOPTimeIncLen; //original 0x0e 15 frame per sec
//*P_VOPTimeInc_low= 0x01;
//*P_VOPTimeInc_high= 0x00;
//*P_VOPTimeIncRes_low=0x0f;
//*P_VOPTimeIncRes_high=0x00;
//------------------------------------------------------------//
//----------------------- mv_max_enc ------------------------//
//------------------------------------------------------------//
//*P_MPEG4_MODE_CTRL1 = 0x06;
*P_MPEG4_MODE_CTRL1 = 0xc6;//yuv not full range
// fill I Qscale
*P_MPEG4_IFRAME_QSCALE = 0x02;//5
// fill P Qscale
*P_MPEG4_PFRAME_QSCALE = 0x02;//5
#ifdef H263_CODEC
*P_MPEG4_H263_CTRL = 0x01 + H263_FORMAT; //bit0 Encoding/decoding 1:enable
// 0:disable
//bit3-1 Specify H.263 Format QCIF or others
//bit6 Enable 4MV Decoding mode or not
//bit7 Enable AC Prediction decoding mode or not
*P_MPEG4_H263_STRUCTURE = 0x00; //bit 0 Enable H.263 GOB structure for Encoding/Decoding
//bit7-4 Specify number of bits needed for certain resolution.
#endif
//*P_MPEG4_INT_CTRL = 0x03;//0x0f //add by ww
}
void mp4_set_encode_frame_buffer_address(unsigned int ABBufferSrc,unsigned int CDBufferDst,unsigned int unBuffSize)
{
//---- SET A/B buffer
*P_MPEG4_RAWBUFFER_SEL = 0x00;
*P_MPEG4_RAWBUFFER_SA1 = ABBufferSrc; //0xa0400000
*P_MPEG4_RAWBUFFER_SA2 = ABBufferSrc + unBuffSize; //0xa0430000
*P_MPEG4_RAWBUFFER_SA3 = ABBufferSrc + (unBuffSize*2); //0xa0460000
//------ SET C/D buffer ------//
*P_MPEG4_WRITEBUFFER_SA1 = CDBufferDst; //0xa0590000
*P_MPEG4_WRITEBUFFER_SA2 = CDBufferDst + unBuffSize; //0xa05C0000
*P_MPEG4_VLCBUFFER_SEL = 0x00;
*P_MPEG4_VLCBUFFER_SA2 = 0;
}
unsigned int mp4_compress_frame(unsigned int vlc_address,unsigned int frame)
{
unsigned int vlc_size;
unsigned int i;
unsigned int picture_address_ptr;
unsigned int rd_buffer_switch=frame&0x00000001;
unsigned int wd_buffer_switch=~rd_buffer_switch;
wd_buffer_switch=wd_buffer_switch&0x00000001;
picture_address_ptr=*P_CSI_BUFFER_SEL;
if(picture_address_ptr==0) picture_address_ptr=2;
else picture_address_ptr--;
//---- SET A/B buffer
*P_MPEG4_RAWBUFFER_SEL = picture_address_ptr;
//------ SET C/D buffer ------//
// RD Bufer
*P_MPEG4_REFBUFFER_SEL = rd_buffer_switch;
//////print2("P_MPEG4_REFBUFFER_SEL = ",0,rd_buffer_switch);
// WR Bufer
*P_MPEG4_WRITEBUFFER_SEL = wd_buffer_switch;
// print2("P_MPEG4_REFBUFFER_SEL = ",0,wd_buffer_switch);
//---- SET VLCA/VLCB buffer
// vlcoffset
i=vlc_address&0xfffffc00;
*P_MPEG4_VLCBUFFER_SA1 = i;
*P_MPEG4_VLCOFFSET_SALOW = vlc_address;
i=vlc_address&0x00000300;
i=i>>8;
*P_MPEG4_VLCOFFSET_SAMID = i;
*P_MPEG4_VLCOFFSET_SAHIGH = 0;
///////////////////////////////////////////////////////
// cpu sof information
*P_MPEG4_COMPRESS_CTRL = 0x08;
// dummy delay
for (i=0;i<10;i++);
// sof to trigger compression
*P_MPEG4_COMPRESS_CTRL = 0x01;
// print1("wait frame eof\n");
// Loop until eof is set
while ((*P_MPEG4_COMPRESS_CTRL & 0x02) == 0);
// print1("frame eof active ...\n");
//---- dump encoded frame from MIU
vlc_size=*P_MPEG4_VLCSIZE_HIGH;
vlc_size=vlc_size<<8;
vlc_size=vlc_size|*P_MPEG4_VLCSIZE_MID;
vlc_size=vlc_size<<8;
vlc_size=vlc_size|*P_MPEG4_VLCSIZE_LOW;
return vlc_size;
}
void mp4_set_decode_frame_buffer_address(unsigned int MP4WBuffAddrSrc,unsigned int TVBuffAddrDst,unsigned int unBuffSize)
{
unsigned int ulSize;
//---- Buffer control setting
if(g_unMP4HW_RunMode==NORMAL_MODE)
{
#ifdef DECODE_SOFT_SWITCH_BUFF
*P_BUFCTRL_BUFFER_SEL = 0x0000;//0x1040;//using software(0)/hardware(1) to control buffer change
*P_BUFCTRL_MODE_CTRL1 = 0x001A;//MP4 trigger TVE triple buffer switch
#else
*P_BUFCTRL_BUFFER_SEL = 0x1040;//0x1040;//using software(0)/hardware(1) to control buffer change
*P_BUFCTRL_MODE_CTRL1 = 0x001b;//MP4 trigger TVE triple buffer switch
#endif
}
else if(g_unMP4HW_RunMode==CONFERENCE_MODE)
{
#ifdef DECODE_SOFT_SWITCH_BUFF
*P_BUFCTRL_BUFFER_SEL = 0x0001;//0x1040;//using software(0)/hardware(1) to control buffer change
*P_BUFCTRL_MODE_CTRL1 = 0x0007;//MP4 trigger TVE triple buffer switch
#else
*P_BUFCTRL_BUFFER_SEL = 0x1040;//0x1040;//using software(0)/hardware(1) to control buffer change
*P_BUFCTRL_MODE_CTRL1 = 0x001b;//MP4 trigger TVE triple buffer switch
#endif
}
else
{
//
}
// *P_TV_BUFFERA_SEL = 0x00000001;
if( (g_unMP4HW_dvWidth <= 320) && (g_unMP4HW_dvHigh <= 240))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -