📄 mfc.c
字号:
/**************************************************************************************
*
* Project Name : S3C6400 Validation
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is only for validating functions of the S3C6400.
* Anybody can use this software without our permission.
*
*--------------------------------------------------------------------------------------
*
* File Name : mfc.c
*
* File Description : This file implements the API functons for MFC.
*
* Author : Haksoo,Kim
* Dept. : AP Development Team
* Created Date : 2006/12/21
* Version : 0.1
*
* History
* - Created(Haksoo,Kim 2006/12/21)
*
**************************************************************************************/
#include "option.h"
#include "library.h"
#include "sfr6400.h"
#include "mfc.h"
//#include "Prism_S_V131.h" // firmware (80KB)
//#include "Prism_S_V133.h" // firmware (80KB)
//#include "Prism_S_V127_clock_problem_Beta.h" //firmware (80KB)
//#include "Prism_S_V133_clock_problem_Beta.h" //firmware (80KB)
#include "Prism_S_V134.h" //firmware (80KB)
#include <string.h>
#include <stdlib.h>
//#define DBG_MFC
#ifdef DBG_MFC
#define DbgMfc Disp
#else
#define DbgMfc(...)
#endif
#if 0
#define mfcOutp32(addr, data) {Disp("Outp1w(32'h%x, 32'h%x);\n", (addr), (data)); (*(volatile u32 *)(addr) = (data)); }
#define mfcInp32(addr, data) {((data) = (*(volatile u32 *)(addr))); Disp("Inp1w(32'h%x, 32'h%x);\n", (addr), (data)); }
#else
#define mfcOutp32 Outp32
#define mfcInp32 Inp32
#endif
enum MFC_REG
{
CODE_RUN = MFC_BASE+0x000,
// [0] 1=Start the bit processor, 0=Stop.
CODE_DN_LOAD = MFC_BASE+0x004,
// [15:0]
// [28:16]
HOST_INTR = MFC_BASE+0x008,
// [0] Write '1' to this bit to request an interrupt to BIT
BITS_INT_CLEAR = MFC_BASE+0x00c,
// [0]
BITS_INT_STAT = MFC_BASE+0x010,
// [0] 1 means that BIT interrupt to the host is asserted.
BITS_CODE_RESET = MFC_BASE+0x014,
BITS_CUR_PC = MFC_BASE+0x018,
CODE_BUF_ADDR = MFC_BASE+0x100,
WORK_BUF_ADDR = MFC_BASE+0x104,
PARA_BUF_ADDR = MFC_BASE+0x108,
STREAM_BUF_CTRL = MFC_BASE+0x10c,
FRAME_BUF_CTRL = MFC_BASE+0x110,
DEC_FUNC_CTRL = MFC_BASE+0x114,
WORK_BUF_CTRL = MFC_BASE+0x11c,
BITS_RD_PTR0 = MFC_BASE+0x120,
BITS_WR_PTR0 = MFC_BASE+0x124,
BITS_RD_PTR1 = MFC_BASE+0x128,
BITS_WR_PTR1 = MFC_BASE+0x12c,
BITS_RD_PTR2 = MFC_BASE+0x130,
BITS_WR_PTR2 = MFC_BASE+0x134,
BITS_RD_PTR3 = MFC_BASE+0x138,
BITS_WR_PTR3 = MFC_BASE+0x13c,
BITS_RD_PTR4 = MFC_BASE+0x140,
BITS_WR_PTR4 = MFC_BASE+0x144,
BITS_RD_PTR5 = MFC_BASE+0x148,
BITS_WR_PTR5 = MFC_BASE+0x14c,
BITS_RD_PTR6 = MFC_BASE+0x150,
BITS_WR_PTR6 = MFC_BASE+0x154,
BITS_RD_PTR7 = MFC_BASE+0x158,
BITS_WR_PTR7 = MFC_BASE+0x15c,
BUSY_FLAG = MFC_BASE+0x160,
RUN_CMD = MFC_BASE+0x164,
RUN_INDEX = MFC_BASE+0x168,
RUN_COD_STD = MFC_BASE+0x16c,
INT_ENABLE = MFC_BASE+0x170,
INT_REASON = MFC_BASE+0x174,
// DEC_SEQ_INIT Parameter reg
// R/W reg
DEC_SEQ_BIT_BUF_ADDR = MFC_BASE+0x180,
DEC_SEQ_BIT_BUF_SIZE = MFC_BASE+0x184,
DEC_SEQ_OPTION = MFC_BASE+0x188,
DEC_SEQ_PRO_BUF = MFC_BASE+0x18c,
DEC_SEQ_TMP_BUF_1 = MFC_BASE+0x190,
DEC_SEQ_TMP_BUF_2 = MFC_BASE+0x194,
DEC_SEQ_TMP_BUF_3 = MFC_BASE+0x198,
DEC_SEQ_TMP_BUF_4 = MFC_BASE+0x19c,
DEC_SEQ_TMP_BUF_5 = MFC_BASE+0x1a0,
// R reg
RET_SEQ_SUCCESS = MFC_BASE+0x1c0,
RET_DEC_SEQ_SRC_SIZE = MFC_BASE+0x1c4,
RET_DEC_SEQ_SRC_FRAME_RATE = MFC_BASE+0x1c8,
RET_DEC_SEQ_FRAME_NEED_COUNT = MFC_BASE+0x1cc,
RET_DEC_SEQ_FRAME_DELAY = MFC_BASE+0x1d0,
RET_DEC_SEQ_INFO = MFC_BASE+0x1d4,
// ENC_SEQ_INIT Parameter reg
// R/W reg
ENC_SEQ_BIT_BUF_ADDR = MFC_BASE+0x180,
ENC_SEQ_BIT_BUF_SIZE = MFC_BASE+0x184,
ENC_SEQ_OPTION = MFC_BASE+0x188,
ENC_SEQ_COD_STD = MFC_BASE+0x18c,
ENC_SEQ_SRC_SIZE = MFC_BASE+0x190,
ENC_SEQ_SRC_FRAME_RATE = MFC_BASE+0x194,
ENC_SEQ_MP4_PARA = MFC_BASE+0x198,
ENC_SEQ_263_PARA = MFC_BASE+0x19c,
ENC_SEQ_264_PARA = MFC_BASE+0x1a0,
ENC_SEQ_SLICE_MODE = MFC_BASE+0x1a4,
ENC_SEQ_GOP_NUM = MFC_BASE+0x1a8,
ENC_SEQ_RC_PARA = MFC_BASE+0x1ac,
ENC_SEQ_RC_BUF_SIZE = MFC_BASE+0x1b0,
ENC_SEQ_INTRA_MB = MFC_BASE+0x1b4,
ENC_SEQ_FMO = MFC_BASE+0x1b8,
ENC_SEQ_TMP_BUF_1 = MFC_BASE+0x1d0,
ENC_SEQ_TMP_BUF_2 = MFC_BASE+0x1d4,
ENC_SEQ_TMP_BUF_3 = MFC_BASE+0x1d8,
ENC_SEQ_TMP_BUF_4 = MFC_BASE+0x1dc,
// R reg
//ENC_SEQ_SUCCESS = MFC_BASE+0x1c0, // same as DEC_SEQ_INIT
// DEC_PIC_RUN Parameter reg
// R/W reg
DEC_PIC_ROT_MODE = MFC_BASE+0x180,
DEC_PIC_ROT_ADDR_Y = MFC_BASE+0x184,
DEC_PIC_ROT_ADDR_CB = MFC_BASE+0x188,
DEC_PIC_ROT_ADDR_CR = MFC_BASE+0x18c,
DEC_PIC_DEBLOCK_ADDR_Y = MFC_BASE+0x190,
DEC_PIC_DEBLOCK_ADDR_CB = MFC_BASE+0x194,
DEC_PIC_DEBLOCK_ADDR_CR = MFC_BASE+0x198,
DEC_PIC_ROT_STRIDE = MFC_BASE+0x19c,
DEC_PIC_CHUNK_SIZE = MFC_BASE+0x1a8,
DEC_PIC_BB_START = MFC_BASE+0x1ac,
DEC_PIC_START_BYTE = MFC_BASE+0x1b0,
// R reg
RET_PIC_FRAME_NUM = MFC_BASE+0x1c0,
RET_DEC_PIC_INDEX = MFC_BASE+0x1c4,
RET_DEC_PIC_ERR_MB_NUM = MFC_BASE+0x1c8,
RET_DEC_PIC_TYPE = MFC_BASE+0x1cc,
// ENC_PIC_RUN Parameter reg
// R/W reg
ENC_PIC_SRC_ADDR_Y = MFC_BASE+0x180,
ENC_PIC_SRC_ADDR_CB = MFC_BASE+0x184,
ENC_PIC_SRC_ADDR_CR = MFC_BASE+0x188,
ENC_PIC_QS = MFC_BASE+0x18c,
ENC_PIC_ROT_MODE = MFC_BASE+0x190,
ENC_PIC_OPTION = MFC_BASE+0x194,
// R reg
// RET_ENC_PIC_FRAME_NUM = MFC_BASE+0x1c0, // same as in DEC_PIC_RUN
RET_ENC_PIC_TYPE = MFC_BASE+0x1c4,
RET_ENC_PIC_INDEX = MFC_BASE+0x1c8,
RET_ENC_PIC_SLICE_NUM = MFC_BASE+0x1cc,
// SET_FRAME_BUFFER Parameter reg
SET_FRAME_BUF_NUM = MFC_BASE+0x180,
SET_FRAME_BUF_STRIDE = MFC_BASE+0x184,
// ENC_HEADER Parameter reg
ENC_HEADER_CODE = MFC_BASE+0x180,
// DEC_PARA_SET reg
DEC_PARA_SET_TYPE = MFC_BASE+0x180,
DEC_PARA_SET_SIZE = MFC_BASE+0x184,
// ENC_PARA_SET reg
// R/W reg
ENC_PARA_SET_TYPE = MFC_BASE+0x180,
// R reg
RET_ENC_PARA_SET_SIZE = MFC_BASE+0x1c0,
// GET_FW_VER reg
// R reg
RET_GET_FW_VER = MFC_BASE+0x1c0,
SW_RESET = MFC_BASE+0xe00,
BITS_CODE_INPUT = MFC_BASE+0x1000
};
// STREAM_BUF_CTRL (0x10c)
#define STREAM_ENDIAN_LITTLE (0<<0)
#define STREAM_ENDIAN_BIG (1<<0)
#define BUF_STATUS_FULL_EMPTY_CHECK_BIT (0<<1)
#define BUF_STATUS_NO_CHECK_BIT (1<<1)
#define NOT_FLUSH_BUF_IN_ENCODING (0<<2)
#define FLUSH_BUF_IN_ENCODING (1<<2)
#define RESET_BUF_AT_EVERY_ENCODING (2<<2)
// FRAME_BUF_CTRL (0x110)
#define FRAME_MEM_ENDIAN_LITTLE (0<<0)
#define FRAME_MEM_ENDIAN_BIG (1<<0)
// INT_REASON (0x170)
#define INT_DNLOAD_DONE_BIT (1<<0)
#define INT_SEQ_INIT_BIT (1<<1)
#define INT_SEQ_END_BIT (1<<2)
#define INT_PIC_RUN_BIT (1<<3)
#define INT_SET_FRAME_BUF (1<<4)
#define INT_ENC_HEADER (1<<5)
#define INT_ENC_PARA_SET (1<<6)
#define INT_DEC_PARA_SET (1<<7)
#define INT_BIT_BUF_EMPTY_BIT (1<<14)
#define INT_BIT_BUF_FULL_BIT (1<<15)
#define INT_ALL_BIT (0xc0ff)
// DEC_SEQ_OPTION (0x18c)
#define MP4_DBK_DISABLE (0<<0)
#define MP4_DBK_ENABLE (1<<0)
#define REORDER_DISABLE (0<<1)
#define REORDER_ENABLE (1<<1)
#define FILEPLAY_ENABLE (1<<2)
#define FILEPLAY_DISABLE (0<<2)
#define DYNBUFALLOC_ENABLE (1<<3)
#define DYNBUFALLOC_DISABLE (0<<3)
MFC oMfc;
void MFC_InitProcessForDecodingMpeg4(
u32 uProcessIdx, u32 uStreamBufStAddr, u32 uStreamBufSize,
u32 uFrameBufStAddr, bool bDecRotEn, bool bMp4DeblkEn)
{
MFC_InitProcessForDecoding(uProcessIdx, MP4_DEC, uStreamBufStAddr, uStreamBufSize,
uFrameBufStAddr, bDecRotEn, bMp4DeblkEn, false);
}
void MFC_InitProcessForDecodingH264(
u32 uProcessIdx, u32 uStreamBufStAddr, u32 uStreamBufSize,
u32 uFrameBufStAddr, bool bDecRotEn, bool bH264ReorderEn)
{
MFC_InitProcessForDecoding(uProcessIdx, AVC_DEC, uStreamBufStAddr, uStreamBufSize,
uFrameBufStAddr, bDecRotEn, false, bH264ReorderEn);
}
void MFC_InitProcessForDecodingVc1(
u32 uProcessIdx, u32 uStreamBufStAddr, u32 uStreamBufSize, u32 uFrameBufStAddr, bool bDecRotEn)
{
MFC_InitProcessForDecoding(uProcessIdx, VC1_DEC, uStreamBufStAddr, uStreamBufSize,
uFrameBufStAddr, bDecRotEn, false, false);
}
void MFC_InitProcessForDmbDecoding(
u32 uProcessIdx, u32 uStreamBufStAddr, u32 uStreamBufSize, u32 uFrameBufStAddr, bool bDecRotEn)
{
u32 uStreamBufSizeCeilingToKbMultiple;
bool stat;
float frameRate;
u32 picX, picY;
u32 uNumOfRefReconFrame, uFrameBufNum;
u32 uStride, uHeight;
Assert(uProcessIdx < MAX_PROCESS_NUM);
oMfc.m_eCodecMode[uProcessIdx] = AVC_DEC;
uStreamBufSizeCeilingToKbMultiple = (uStreamBufSize+1023)/1024*1024;
oMfc.m_uStreamBufStAddr[uProcessIdx] = uStreamBufStAddr;
oMfc.m_uStreamBufEndAddr[uProcessIdx] = uStreamBufStAddr + uStreamBufSizeCeilingToKbMultiple;
oMfc.m_uStreamBufByteSize[uProcessIdx] = uStreamBufSizeCeilingToKbMultiple;
oMfc.m_uBitRdPtr[uProcessIdx] =
(uProcessIdx == 0) ? BITS_RD_PTR0 :
(uProcessIdx == 1) ? BITS_RD_PTR1 :
(uProcessIdx == 2) ? BITS_RD_PTR2 :
(uProcessIdx == 3) ? BITS_RD_PTR3 :
(uProcessIdx == 4) ? BITS_RD_PTR4 :
(uProcessIdx == 5) ? BITS_RD_PTR5 :
(uProcessIdx == 6) ? BITS_RD_PTR6 : BITS_RD_PTR7;
oMfc.m_uBitWrPtr[uProcessIdx] =
(uProcessIdx == 0) ? BITS_WR_PTR0 :
(uProcessIdx == 1) ? BITS_WR_PTR1 :
(uProcessIdx == 2) ? BITS_WR_PTR2 :
(uProcessIdx == 3) ? BITS_WR_PTR3 :
(uProcessIdx == 4) ? BITS_WR_PTR4 :
(uProcessIdx == 5) ? BITS_WR_PTR5 :
(uProcessIdx == 6) ? BITS_WR_PTR6 : BITS_WR_PTR7;
mfcOutp32(oMfc.m_uBitRdPtr[uProcessIdx], oMfc.m_uStreamBufStAddr[uProcessIdx]);
mfcOutp32(oMfc.m_uBitWrPtr[uProcessIdx], oMfc.m_uStreamBufStAddr[uProcessIdx]+uStreamBufSize);
mfcOutp32(DEC_SEQ_BIT_BUF_ADDR, oMfc.m_uStreamBufStAddr[uProcessIdx]);
mfcOutp32(DEC_SEQ_BIT_BUF_SIZE, oMfc.m_uStreamBufByteSize[uProcessIdx]/1024); // KB unit
mfcOutp32(DEC_SEQ_OPTION, MP4_DBK_DISABLE|REORDER_DISABLE);
oMfc.m_bIsNoMoreStream[uProcessIdx] = false;
MFC_IssueCmd(uProcessIdx, SEQ_INIT);
stat = MFC_IsCmdFinished();
if(stat == false)
{
Disp("\n There is an error in the SEQ_INIT result\n");
return;
}
MFC_GetDecSrcFormat(&picX, &picY, &frameRate);
oMfc.m_uPicX[uProcessIdx] = picX;
oMfc.m_uPicY[uProcessIdx] = picY;
Disp("%d x %d @%.2f Hz\n", picX, picY, frameRate);
Assert(picX > 0);
Assert(picY > 0);
oMfc.m_bDecRotEn[uProcessIdx] = bDecRotEn;
oMfc.m_uRotFrameIdx[uProcessIdx] = 0;
oMfc.m_uMp4DeblockFrameIdx[uProcessIdx] = 0;
oMfc.m_uFrameIndex[uProcessIdx] = 0;
oMfc.m_uFrameDelayCount[uProcessIdx] = mfcInp32(RET_DEC_SEQ_FRAME_DELAY);
//DbgMfc("Delay Frame num=%d\n", oMfc.m_uFrameDelayCount[uProcessIdx]);
uNumOfRefReconFrame = 5; // Ref:3 + Recon:2
oMfc.m_uRefFrameNum[uProcessIdx] = uNumOfRefReconFrame;
uFrameBufNum = (oMfc.m_bDecRotEn[uProcessIdx]) ? uNumOfRefReconFrame+2 : uNumOfRefReconFrame;
uStride = (picX%16 == 0) ? picX : (picX+15)/16*16;
uHeight = (picY%16 == 0) ? picY : (picY+15)/16*16;
Assert(uStride <= 352);
Assert(uHeight <= 288);
MFC_InitDecFrameBuffer(uProcessIdx, uFrameBufNum, uStride, uHeight, uFrameBufStAddr);
MFC_IssueCmdOfSetFrameBuffer(uProcessIdx, uNumOfRefReconFrame, uStride);
}
void MFC_InitProcessForDecoding(
u32 uProcessIdx, MFC_CODEC_MODE eCodecMode, u32 uStreamBufStAddr, u32 uStreamBufSize,
u32 uFrameBufStAddr, bool bDecRotEn, bool bMp4DeblkEn, bool bH264ReorderEn)
{
u32 uStreamBufSizeCeilingToKbMultiple;
u32 uMp4DecDeblkMode;
u32 uH264DecReorderMode;
bool stat;
float frameRate;
u32 picX, picY;
u32 uNumOfRefReconFrame;
u32 uStride;
u32 uHeight;
u32 uFrameBufNumTemp;
u32 uFrameBufNum;
Assert(uProcessIdx < MAX_PROCESS_NUM);
Assert(eCodecMode == MP4_DEC || eCodecMode == AVC_DEC || eCodecMode == VC1_DEC);
oMfc.m_eCodecMode[uProcessIdx] = eCodecMode;
uStreamBufSizeCeilingToKbMultiple = (uStreamBufSize+1023)/1024*1024;
oMfc.m_uStreamBufStAddr[uProcessIdx] = uStreamBufStAddr;
oMfc.m_uStreamBufEndAddr[uProcessIdx] = uStreamBufStAddr + uStreamBufSizeCeilingToKbMultiple;
oMfc.m_uStreamBufByteSize[uProcessIdx] = uStreamBufSizeCeilingToKbMultiple;
oMfc.m_uBitRdPtr[uProcessIdx] =
(uProcessIdx == 0) ? BITS_RD_PTR0 :
(uProcessIdx == 1) ? BITS_RD_PTR1 :
(uProcessIdx == 2) ? BITS_RD_PTR2 :
(uProcessIdx == 3) ? BITS_RD_PTR3 :
(uProcessIdx == 4) ? BITS_RD_PTR4 :
(uProcessIdx == 5) ? BITS_RD_PTR5 :
(uProcessIdx == 6) ? BITS_RD_PTR6 : BITS_RD_PTR7;
oMfc.m_uBitWrPtr[uProcessIdx] =
(uProcessIdx == 0) ? BITS_WR_PTR0 :
(uProcessIdx == 1) ? BITS_WR_PTR1 :
(uProcessIdx == 2) ? BITS_WR_PTR2 :
(uProcessIdx == 3) ? BITS_WR_PTR3 :
(uProcessIdx == 4) ? BITS_WR_PTR4 :
(uProcessIdx == 5) ? BITS_WR_PTR5 :
(uProcessIdx == 6) ? BITS_WR_PTR6 : BITS_WR_PTR7;
mfcOutp32(oMfc.m_uBitRdPtr[uProcessIdx], oMfc.m_uStreamBufStAddr[uProcessIdx]);
mfcOutp32(oMfc.m_uBitWrPtr[uProcessIdx], oMfc.m_uStreamBufStAddr[uProcessIdx]+uStreamBufSize);
mfcOutp32(DEC_SEQ_BIT_BUF_ADDR, oMfc.m_uStreamBufStAddr[uProcessIdx]);
mfcOutp32(DEC_SEQ_BIT_BUF_SIZE, oMfc.m_uStreamBufByteSize[uProcessIdx]/1024); // KB unit
oMfc.m_bMp4DecDeblkMode[uProcessIdx] = (eCodecMode == MP4_DEC) ? bMp4DeblkEn : false;
uMp4DecDeblkMode = (oMfc.m_bMp4DecDeblkMode[uProcessIdx]) ? MP4_DBK_ENABLE : MP4_DBK_DISABLE;
uH264DecReorderMode = (bH264ReorderEn) ? REORDER_ENABLE : REORDER_DISABLE;
mfcOutp32(DEC_SEQ_OPTION, uMp4DecDeblkMode|uH264DecReorderMode);
oMfc.m_bIsNoMoreStream[uProcessIdx] = false;
MFC_IssueCmd(uProcessIdx, SEQ_INIT);
stat = MFC_IsCmdFinished();
if(stat == false)
{
Disp("\n There is an error in the SEQ_INIT result\n");
return;
}
//u32 uFrameBufAddr = oMfc.m_uStreamBufEndAddr[uProcessIdx]+STREAM_WR_SIZE;
MFC_GetDecSrcFormat(&picX, &picY, &frameRate);
oMfc.m_uPicX[uProcessIdx] = picX;
oMfc.m_uPicY[uProcessIdx] = picY;
Disp("%d x %d @%.2f Hz\n", picX, picY, frameRate);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -