📄 mae_wrappers.cpp
字号:
/* <LIC_AMD_STD> * Copyright (C) 2003-2005 Advanced Micro Devices, Inc. All Rights Reserved. * * Unless otherwise designated in writing, this software and any related * documentation are the confidential proprietary information of AMD. * THESE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY * UNLESS OTHERWISE NOTED IN WRITING, EXPRESS OR IMPLIED WARRANTY OF ANY * KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, * NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE AND IN NO * EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER. * * AMD does not assume any responsibility for any errors which may appear * in the Materials nor any responsibility to support or update the * Materials. AMD retains the right to modify the Materials at any time, * without notice, and is not obligated to provide such modified * Materials to you. AMD is not obligated to furnish, support, or make * any further information available to you. * </LIC_AMD_STD> *//* <CTL_AMD_STD> * </CTL_AMD_STD> *//* <DOC_AMD_STD> * </DOC_AMD_STD> */#include <string.h>#include "mae_wrappers.hpp"#include "mae_fe.h"#include "mae_fe_mcomp.h"#include "mae_vpi.h"#include "mae_global.h"#include "mae_pass_thru.h"extern "C"{#include <mae_interface.h>#ifndef MAE_HW #include <cmodelif.h>#endif }C_MAEWrapper * g_MAEWrapper;C_MAEWrapper::C_MAEWrapper (void){ m_nMAELogFlags = k_MAE_Log_nothing;}C_MAEWrapper::~C_MAEWrapper (void){}// HV For Travisvoid C_MAEWrapper::ClearHeaderWords (void) { memset (&pMAEContext->pHeader->header_word0, 0, sizeof(_header_word0)); memset (&pMAEContext->pHeader->header_word1, 0, sizeof(_header_word1)); memset (&pMAEContext->pHeader->header_word2, 0, sizeof(_header_word2)); memset (&pMAEContext->pHeader->header_word3, 0, sizeof(_header_word3));}void C_MAEWrapper::FillMAERegisters (int bInterlaceMode) { pMAERegs->regmask = 0; // Frame sizes pMAERegs->regmask |= PICTURE_SIZE_MASK; // Current Y, U & V pointer masks pMAERegs->regmask |= CUR_Y_MASK; pMAERegs->regmask |= CUR_CB_MASK; pMAERegs->regmask |= CUR_CR_MASK; if (gMAEConfig.nFrameType == PFRAME || gMAEConfig.nFrameType == BFRAME) { pMAERegs->regmask |= FWD_Y_TOP_MASK; pMAERegs->regmask |= FWD_CB_TOP_MASK; pMAERegs->regmask |= FWD_CR_TOP_MASK; if (bInterlaceMode) { pMAERegs->regmask |= FWD_Y_BOT_MASK; pMAERegs->regmask |= FWD_CB_BOT_MASK; pMAERegs->regmask |= FWD_CR_BOT_MASK; } } if (gMAEConfig.nFrameType == BFRAME) { pMAERegs->regmask |= BWD_Y_TOP_MASK; pMAERegs->regmask |= BWD_CB_TOP_MASK; pMAERegs->regmask |= BWD_CR_TOP_MASK; if (bInterlaceMode) { pMAERegs->regmask |= BWD_Y_BOT_MASK; pMAERegs->regmask |= BWD_CB_BOT_MASK; pMAERegs->regmask |= BWD_CR_BOT_MASK; } } // Config0 reg pMAERegs->regmask |= CONFIG0_MASK; // Let us dump all this into pMAEConfig WrapSetRegisters (pMAERegs, 0); // Progressive only as of now!!}void C_MAEWrapper::InitMBData (int nNumMVs, int nNumWMs) { // If there are Motion Vectors, setup the pMV pointer. if (nNumMVs) { pMAEContext->pMV = WrapSkipMVs(pMAEContext->pMB, 0, 0); // Also, reset the MV data memset(&pMAEContext->pMV[0], 0, nNumMVs * sizeof(uint32)); } // Move the Data Block pointer accordingly based on // the number of Weighting Matrices & Motion Vectors. pMAEContext->pDataBlock = (uint16 *)WrapSkipMVs(pMAEContext->pMB, nNumWMs, nNumMVs);}// ***************************************************************************//// Function: mpeg4_swizzle_128b_16a////// Parameters: Source & Destination pointers//// Return Value: void//// Notes: Swizzles the source data in Big-Endian format. This is// the format in which MAE-FE expects the data in.//// ***************************************************************************void C_MAEWrapper::mpeg4_swizzle_128b_16a(uint16 *src, uint16 *dst) { int i; for (i = 0;i < 64;i+=2) { dst[i+1] = src[i+0]; dst[i+0] = src[i+1]; }}int C_MAEWrapper::CallCModel (int nNumMVs, int nCodingType, unsigned char bQPEL) { int index, nNumBytes = 0, nNumWMs = 0; int MVX, MVY, shift, xDivisor, yDivisor; int nLinesize = pMAERegs->picture_size.linesiz; int nHeight = pMAERegs->picture_size.height; // Adjust the xpos & ypos as per the old code (needed for MV clipping) // Since we did a pos*2 (instead of pos*16 which the old code did), // lets just do an additional pos*8 to make the clipping logic fall in place int xpos = g_pHeader3->xpos * 8; int ypos = g_pHeader3->ypos * 8;// HV - Perf Changes// uint16 *DestBlk, SrcBlk[BLOCK_SQUARE_SIZE]; int nCodedBlocks = 0;#ifdef USE_CMODELIF wrap_extra_info *pWrapOOBData;#endif // Lets fill out all the data for this MB // ************************************** // Set the MBMode for all blocks if (g_pHeader2->mbmode == MBM_FORWARD) g_pHeader2->mbmode = MBMODE_FWD_ALL_420; else if (g_pHeader2->mbmode == MBM_BACKWARD) g_pHeader2->mbmode = MBMODE_BWD_ALL_420; else if (g_pHeader2->mbmode == MBM_BIDIRECTIONAL) g_pHeader2->mbmode = MBMODE_BID_ALL_420; // Y precision value if (bQPEL) g_pHeader3->mcprecy = MAE_QUARTER_PEL; else g_pHeader3->mcprecy = MAE_HALF_PEL_BILINEAR; // U & V precision value g_pHeader3->mcprecuv = MAE_HALF_PEL_BILINEAR; if (g_pHeader2->mbmode != MBMODE_INTRA_ALL) { shift = 0; if (g_pHeader3->mbtype == MBT_16x8) shift = 1; // NOTE: There are still cases in the reference source code where // the Y shift right by 1 is used before calling this function - // this is done mainly so that an accurate assessment of whether // we need to flip from MAE to the reference implementation for // motion vector processing can be done. // Clip luma motion vectors yDivisor = 1; if (g_pHeader3->fp == MAE_FIELD_PREDICTION) yDivisor = 2; for (index = 0; index <= 7; index++) { MVX = (int)((int16)((g_TempMAEMB.mv[index] >> 16) & 0x0000FFFF)); MVY = (int)((int16)(g_TempMAEMB.mv[index] & 0x0000FFFF)); // Only lumas can have either QUARTER_PEL or HALF_PEL_BILINEAR // MVs. We need to do the clipping accordingly. // ************************************************************ if(g_pHeader3->mcprecy == MAE_QUARTER_PEL) this->LimitMVRangeToExtendedBBQuarterPel (xpos, ypos/yDivisor, &MVX, &MVY, nLinesize, nHeight/yDivisor, true, index); else this->LimitMVRangeToExtendedBBHalfPel (xpos, ypos/yDivisor, &MVX, &MVY, nLinesize, nHeight/yDivisor, true, index); g_TempMAEMB.mv[index] = (MVX << 16) | ((MVY >> shift) & 0x0000FFFF); } // Clip chroma motion vectors xDivisor = 2; yDivisor = 2; if (g_pHeader3->fp == MAE_FIELD_PREDICTION) yDivisor = 4; for (index = 0; index <= 1; index++) { MVX = (int)((int16)((g_TempMAEMB.mv_uv[index] >> 16) & 0x0000FFFF)); MVY = (int)((int16)(g_TempMAEMB.mv_uv[index] & 0x0000FFFF)); this->LimitMVRangeToExtendedBBHalfPel (xpos/xDivisor, ypos/yDivisor, &MVX, &MVY, nLinesize/xDivisor, nHeight/yDivisor, false, index); g_TempMAEMB.mv_uv[index] = (MVX << 16) | ((MVY >> shift) & 0x0000FFFF); MVX = (int)((int16)((g_TempMAEMB.mv_uv1[index] >> 16) & 0x0000FFFF)); MVY = (int)((int16)(g_TempMAEMB.mv_uv1[index] & 0x0000FFFF)); this->LimitMVRangeToExtendedBBHalfPel (xpos/xDivisor, ypos/yDivisor, &MVX, &MVY, nLinesize/xDivisor, nHeight/yDivisor, false, index); g_TempMAEMB.mv_uv1[index] = (MVX << 16) | ((MVY >> shift) & 0x0000FFFF); } // MV data, 4 for forward ref & 4 for backward ref (lumas - Y) // For MBT_16x16 & forward MC only, all of the first 4 MVs should point to // the same value if ((g_pHeader2->mbmode != MBMODE_BID_ALL_420) || ((g_pHeader3->mbtype == MBT_16x16) || (g_pHeader3->mbtype == MBT_16x8))) { g_TempMAEMB.mv[4] = 0; g_TempMAEMB.mv[5] = 0; g_TempMAEMB.mv[6] = 0; g_TempMAEMB.mv[7] = 0; } // Now that we have done all the clipping, lets copy out the MVs if (g_pHeader2->mbmode == MBMODE_BID_ALL_420) { if(g_pHeader3->mbtype == MBT_16x16) { // Ys pMAEContext->pMV[0] = g_TempMAEMB.mv[0]; pMAEContext->pMV[1] = g_TempMAEMB.mv[1]; pMAEContext->pMV[2] = g_TempMAEMB.mv[2]; pMAEContext->pMV[3] = g_TempMAEMB.mv[3]; // UVs pMAEContext->pMV[4] = g_TempMAEMB.mv_uv[0]; pMAEContext->pMV[5] = g_TempMAEMB.mv_uv[1]; } else if(g_pHeader3->mbtype == MBT_16x8) { // Ys pMAEContext->pMV[0] = g_TempMAEMB.mv[0]; pMAEContext->pMV[1] = g_TempMAEMB.mv[1]; pMAEContext->pMV[2] = g_TempMAEMB.mv[2]; pMAEContext->pMV[3] = g_TempMAEMB.mv[3]; // UVs pMAEContext->pMV[4] = g_TempMAEMB.mv_uv[0]; pMAEContext->pMV[5] = g_TempMAEMB.mv_uv[1]; pMAEContext->pMV[6] = g_TempMAEMB.mv_uv1[0]; pMAEContext->pMV[7] = g_TempMAEMB.mv_uv1[1]; } else if(g_pHeader3->mbtype == MBT_8x8) { // Ys pMAEContext->pMV[0] = g_TempMAEMB.mv[0]; pMAEContext->pMV[1] = g_TempMAEMB.mv[1]; pMAEContext->pMV[2] = g_TempMAEMB.mv[2]; pMAEContext->pMV[3] = g_TempMAEMB.mv[3]; pMAEContext->pMV[4] = g_TempMAEMB.mv[4]; pMAEContext->pMV[5] = g_TempMAEMB.mv[5]; pMAEContext->pMV[6] = g_TempMAEMB.mv[6]; pMAEContext->pMV[7] = g_TempMAEMB.mv[7]; // UVs pMAEContext->pMV[8] = g_TempMAEMB.mv_uv[0]; pMAEContext->pMV[9] = g_TempMAEMB.mv_uv[1]; } } // FWD OR BWD ONLY CASES else { // Ys pMAEContext->pMV[0] = g_TempMAEMB.mv[0]; pMAEContext->pMV[1] = g_TempMAEMB.mv[1]; pMAEContext->pMV[2] = g_TempMAEMB.mv[2]; pMAEContext->pMV[3] = g_TempMAEMB.mv[3]; // UVs pMAEContext->pMV[4] = g_TempMAEMB.mv_uv[0]; // UVs if (g_pHeader3->mbtype == MBT_16x8) pMAEContext->pMV[5] = g_TempMAEMB.mv_uv1[0]; } } // Update the wrap_extra_info stuff only we are using the CModel#ifdef USE_CMODELIF // Clear the wrapper Out Of Band data fields pWrapOOBData = (wrap_extra_info *)pMAEContext->pWrapExtraInfo; memset(pWrapOOBData,0,sizeof(wrap_extra_info)); // Now, setup some fields pWrapOOBData->cur_y_frame = (uint8 *)gMAEConfig.cur_y_frame_ptr; pWrapOOBData->cur_cb_frame = (uint8 *)gMAEConfig.cur_cb_frame_ptr; pWrapOOBData->cur_cr_frame = (uint8 *)gMAEConfig.cur_cr_frame_ptr; pWrapOOBData->nMB = gMAEConfig.nMB; pWrapOOBData->nForceSend = SEND_BATCH; pWrapOOBData->iFrameNum = gMAEConfig.nFrameNum; pWrapOOBData->nFrameType = gMAEConfig.nFrameType; pWrapOOBData->bPureIntra = gMAEConfig.bPureIntra; pWrapOOBData->nDeadZone = 0; pWrapOOBData->pl_mbmode = 0;#endif // Make sure we use the right number of Weighting Matrices the first time we // queue a MB (Intra MB from an Intra frame). Also, reset bFirstTime flag. if(bFirstIntraBlock) { nNumWMs = MAX_WMS; // Reset the bFirstIntraBlock to FALSE as we gathered all // pointers needed for the very first block bFirstIntraBlock = FALSE; } if (nCodingType != MACROBLOCK_SKIPPED) { nCodedBlocks = BLOCKS_FOR_420_FORMAT;// HV - Perf Changes// Since we are doing inline conversion into Big-Endian mode// we don't need to copy & swizzle here (a big saving)/* // Point DestBlk to the first block (in this MB) DestBlk = pMAEContext->pDataBlock; // Swizzle the block data into Big-Endian format for MAE-FE // ******************************************************** for (index=0; index<BLOCKS_FOR_420_FORMAT; index++) { memcpy (SrcBlk, DestBlk, BLOCK_DATA_SIZE_16); mpeg4_swizzle_128b_16a (SrcBlk, DestBlk); // Increment pointer to the next block DestBlk += 64; }*/// ~HV - Perf Changes } nNumBytes = (sizeof(header_words) + (nNumWMs * WM_DATA_SIZE) + (nNumMVs * sizeof(uint32)) + (nCodedBlocks * BLOCK_DATA_SIZE_16)); // Update the Byte Count in the descriptor pMAEContext->desc_size += nNumBytes; return nNumBytes;}// After the CModel(MAE) processed the complete frame, we need to put back // the data in the respective frames for the reference code to display the same.void C_MAEWrapper::PerformPostProcessing(unsigned char* xStartY, unsigned char* xStartU, unsigned char* xStartV,int iMBYstop, int iMBXstop, int m_iFrameWidthYxMBSize, int m_iFrameWidthUVxBlkSize, int nFrameType){ int xmbX, xmbY, nMB = 0; unsigned char *xRowMBY = xStartY; unsigned char *xRowMBU = xStartU; unsigned char *xRowMBV = xStartV;#ifdef COPY_FRAME_FROM_CMODEL for (xmbY = 0; xmbY < iMBYstop; xmbY++) { unsigned char* xCurY = xRowMBY; unsigned char* xCurU = xRowMBU; unsigned char* xCurV = xRowMBV; for (xmbX = 0; xmbX < iMBXstop; xmbX++) { // Frame pointers that the MPEG-4 ref code needs to display Set_MAEConfig_xCurYMBRef (xCurY, "C_MAEWrapper::PerformPostProcessing", __LINE__, __FILE__); Set_MAEConfig_xCurYMBRef (xCurU, "C_MAEWrapper::PerformPostProcessing", __LINE__, __FILE__); Set_MAEConfig_xCurYMBRef (xCurV, "C_MAEWrapper::PerformPostProcessing", __LINE__, __FILE__); // Check to see if we flipped this MB (in Interlaced mode) & if so // do not update the reference code's destination pointers since // they already have the correct data. So, call the Update.. // functions only if we DID NOT flip to reference mode. if (nFlipArray[nMB] == NO_FLIP) { if (nFrameType == IFRAME) UpdateIntraDestPointersForMPEG4(nMB, xCurY, xCurU, xCurV); else UpdateInterDestPointersForMPEG4(nMB, xCurY, xCurU, xCurV); } DumpFinalCheckers(nMB, nFrameType, xCurY, xCurU, xCurV); nMB++; // Increment destination frame pointers xCurY += MB_SIZE; xCurU += BLOCK_SIZE; xCurV += BLOCK_SIZE; } xRowMBY += m_iFrameWidthYxMBSize; xRowMBU += m_iFrameWidthUVxBlkSize; xRowMBV += m_iFrameWidthUVxBlkSize; }#else#ifndef MAE_HW for (xmbY = 0; xmbY < iMBYstop; xmbY++) { unsigned char* xCurY = xRowMBY; unsigned char* xCurU = xRowMBU; unsigned char* xCurV = xRowMBV; for (xmbX = 0; xmbX < iMBXstop; xmbX++) { DumpFinalCheckers(nMB, nFrameType, xCurY, xCurU, xCurV); nMB++; // Increment destination frame pointers xCurY += MB_SIZE; xCurU += BLOCK_SIZE; xCurV += BLOCK_SIZE; } xRowMBY += m_iFrameWidthYxMBSize; xRowMBU += m_iFrameWidthUVxBlkSize; xRowMBV += m_iFrameWidthUVxBlkSize; }#endif#endif}#ifdef DUAL_MODEvoid C_MAEWrapper::DumpFinalCheckers(int nCurMB, int nFrameType, unsigned char *ppxliCodedY, unsigned char *ppxliCodedU, unsigned char *ppxliCodedV)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -