📄 mae_fe.c
字号:
#include "mae_global.h"
#include "mae_fe.h"
#include "queue.h"
#include "mae_hal.h"
#include "mae_memory.h"
#include <windows.h>
YUV_TABLE gYUVTable[NUM_YUVQ_ELEMENTS] =
{
{0, "B0"},
{0, "B1"},
{0, "B2"},
{0, "B3"}
};
EXTERN reg_data RegData[] =
{
{0, "Config Reg"},
{0x4, "cur Y ptr"},
{0x8, "fwd Y ref"},
{0xc, "bwd Y ref"} ,
{0x10, "cur Cb ptr"},
{0x14, "fwd Cb ref"},
{0x18, "bwd Cb ref"},
{0x1c, "cur Cr Ptr"},
{0x20, "fwd Cr ref"},
{0x24, "bwd Cr ref"},
{0x28, "picture size"},
{0x2c, "intensity comp"},
{0x38, "fwd Y bot"},
{0x3c, "fwd Cb bot"} ,
{0x40, "fwd Cr bot"},
{0x44, "bwd Y bot"},
{0x48, "bwd Cb bot"},
{0x4c, "bwd Cr bot"},
{0x5c, "WMV9 pquant"}
};
DWORD g_WaitForEOS = 0;
void program_fe_regs(PMAEQ_T pmaeq, UINT32 ulInterlaced)
{
UINT32 i = 0;
UINT32 val, regmask;
reg_info *preg_values;
#ifdef REG_DEBUG
// KK - rev2
UINT32 val2;
reg_info *preg_values2;
// ~KK - rev2
#endif
if(ulInterlaced)
{
preg_values = (reg_info *)(&pmaeq->fe_reglist_field);
#ifdef REG_DEBUG
preg_values2 = (reg_info *)(&pmaeq->mae_fe_reglist_field); // KK - rev2
#endif
}
else
{
preg_values = (reg_info *)(&pmaeq->fe_reglist);
#ifdef REG_DEBUG
preg_values2 = (reg_info *)(&pmaeq->mae_fe_reglist); // KK - rev2
#endif
}
#ifdef REG_DEBUG
regmask = preg_values2->regmask;
#else
regmask = preg_values->regmask;
#endif
while (regmask)
{
if(regmask & 1)
{
val = *((PUINT32)preg_values+i);
#ifdef REG_DEBUG
val2 = *((PUINT32)preg_values2+i);
if(val != val2)
DPRINTF(MSG_FE, (TEXT("MISMATCH: reg offset %x org val %x MAE comp val %x\n"),RegData[i].offset, val, val2));
au_writel(val, ((UINT32)MAEFE_BASE + RegData[i].offset));
#else
au_writel(val, ((UINT32)MAEFE_BASE + RegData[i].offset));
#endif
DPRINTF(MSG_FE, (TEXT("Reg offset 0x%x Value 0x%x\n"),RegData[i].offset, val));
}
regmask = (regmask >> 1);
i++;
}
// Program the Scratch pad for WMV9 filter processing (Can be done only per run)
au_writel(MAE_PADDR(KRNL_SCRATCH_PAD_BASE), ((UINT32)MAEFE_SCRATCHPAD));
au_writel(MAE_PADDR(pmaeq->descriptors),((UINT32)MAEFE_DMADSCR1));
}
unsigned char update_anchor_frames(void)
{
PMAEQ_T pmaeq;
PYUVQ_T pyuvq;
#ifdef MAE_DBG
int i;
#endif
DPRINTF(MSG_FUNCTION, (TEXT("update_anchor_frames(): entry!!!\n")));
if (!(pmms->fe_proc)) {
DPRINTF(MSG_ERROR, (TEXT("update_anchor_frames(): no FE entry!!!\n")));
return 0;
}
// here we take the newly programmed FE queue entry and adjust the anchor
// frame pointers if needed.
// first check to see if this is an anchor frame, else we're done
if (!(pmms->fe_proc->anchor_flag)){
DPRINTF(MSG_INFO, (TEXT("update_anchor_frames(): no pmms->fe_proc->anchor_flag returning!!!\n")));
return 1;
}
// there are anchors
if (pmms->b_anchor)
{
pmms->b_anchor->anchor_flag = 0; // de-anchor the old one
// if already displayed then free it too
if (pmms->b_anchor->sent_to_be)
{
// for the case where the back anchor is the current be entry
if (pmms->be_proc == pmms->b_anchor)
{
// free the yuv buffer
pyuvq = (PYUVQ_T)pmms->be_proc->pyuvq;
#ifdef MAE_DBG
//DPRINTF(MSG_BE, (TEXT("update_anchor_frames - 1: Freeing YUV buffer \n")));
for(i=0; i<NUM_YUVQ_ELEMENTS; i++)
{
if (gYUVTable[i].pyuvq == pyuvq)
{
//DPRINTF(MSG_BE, (TEXT("%s\n"),gYUVTable[i].szBufName));
break;
}
}
#endif
DLCL_REMOVE(YUVQ_T, &pmms->yuv_inuse, pyuvq);
DLCL_APPEND(YUVQ_T, &pmms->yuv_free, pyuvq);
// MK
if(pmms->nFramesInSystem > 0)
pmms->nFramesInSystem--;
// free the element
DLCL_POP(MAEQ_T, &pmms->be_proc, pmaeq);
if(!pmaeq)
{
DPRINTF(MSG_ERROR, (TEXT("update_anchor_frames()-2: MAEQ null\n")));
return 0;
}
#ifdef MAE_DUMP
sprintf(pmms->pDumpPtr->szDumpStr[pmms->pDumpPtr->numEntries++], "update_anchor: freeing b_anchor # %d\n",pmaeq->tnum);
#endif
DLCL_APPEND(MAEQ_T, &pmms->maeq_free, pmaeq);
pmms->b_anchor = NULL; // init the anchor
}
// and for the case where the back anchor is just one entry in the list
else
{
// free the yuv buffer
pyuvq = (PYUVQ_T)pmms->b_anchor->pyuvq;
#ifdef MAE_DBG
DPRINTF(MSG_BE, (TEXT("update_anchor_frames - 2: Freeing YUV buffer \n")));
for(i=0; i<NUM_YUVQ_ELEMENTS; i++)
{
if (gYUVTable[i].pyuvq == pyuvq)
{
DPRINTF(MSG_BE, (TEXT("%s\n"),gYUVTable[i].szBufName));
break;
}
}
#endif
DLCL_REMOVE(YUVQ_T, &pmms->yuv_inuse, pyuvq);
DLCL_APPEND(YUVQ_T, &pmms->yuv_free, pyuvq);
// free the element
DLCL_POP(MAEQ_T, &pmms->b_anchor, pmaeq);
if(!pmaeq)
{
DPRINTF(MSG_ERROR, (TEXT("update_anchor_frames()-4: MAEQ null\n")));
return 0;
}
// KK - We just pulled the b_anchor frame. Make sure we also pull it out of the be_proc queue.
DLCL_REMOVE(MAEQ_T, &pmms->be_proc, pmaeq);
#ifdef MAE_DUMP
sprintf(pmms->pDumpPtr->szDumpStr[pmms->pDumpPtr->numEntries++], "update_anchor: freeing f_anchor # %d\n",pmaeq->tnum);
#endif
DLCL_APPEND(MAEQ_T, &pmms->maeq_free, pmaeq);
pmms->b_anchor = NULL; // init the anchor
}
}
}
// else if there is only an fanchor
if (pmms->f_anchor)
pmms->b_anchor = pmms->f_anchor; // slide the anchors
// assign the front anchor
pmms->f_anchor = pmms->fe_proc;
DPRINTF(MSG_FUNCTION, (TEXT("update_anchor_frames(): exit pmms->maeq_free %x!!!\n"),pmms->maeq_free));
return 1;
}
unsigned long get_yuvbufferaddr(unsigned long nYUVIndex)
{
unsigned long addr;
if(nYUVIndex >= 3)
return 0;
addr = pmms->yuv_region_offset +(nYUVIndex * SIZE_YUV_FRAME);
addr = (UINT32)(addr + (UINT32)gMaePhysBaseAddress);
//DPRINTF (MSG_BUFFER, (TEXT("get_yuvbufferaddr: addr %x, nYUVIndex %d\n"),addr,nYUVIndex ));
return (addr);
}
unsigned char run_fe_hw(void)
{
PMAEQ_T pmaeq;
PYUVQ_T pyuvq;
DPRINTF(MSG_FE|MSG_TIME, (TEXT("run_fe_hw: Entry: pmms->state 0x%x\n"),pmms->state));
// this state is caught when the app forces a hw start
// check to renable if MAE was frozen
if (pmms->state & MAE_FREEZE) {
pmms->state &= ~(MAE_FREEZE);
}
// this state is caught during an interrupt
// if there is no source or no destination buffer then bail
if (!(pmms->fe_wait)) {
// freeze the pipeline!!!
if(!g_WaitForEOS)
{
pmms->state |= MAE_FREEZE;
}
else
{
pmms->state &= (~ENABLE_FE);
}
return FALSE;
}
// arm the front end
DLCL_POP(MAEQ_T, &pmms->fe_wait, pmaeq);
DPRINTF(MSG_FE|MSG_TIME, (TEXT("pmms->fe_wait: %x\n"), pmms->fe_wait));
// KK - This is a dummy submission that has made it up to here. Freeing it up here.
if(!pmaeq->stream_type)
{
DLCL_REMOVE(DATAQ_T, &pmms->data_inuse, pmaeq->pdataq);
DLCL_APPEND(DATAQ_T, &pmms->data_free, pmaeq->pdataq);
DLCL_APPEND(MAEQ_T, &pmms->maeq_free, pmaeq);
return FALSE;
}
#ifdef NEW_YUV
DLCL_POP(YUVQ_T, &pmms->yuv_free, pyuvq);
if (!pyuvq) {
DPRINTF(MSG_FE, (TEXT("new_yuvbuffer: No free YUV buffer available !!!\n")));
return FALSE;
}
DLCL_APPEND(YUVQ_T, &pmms->yuv_inuse, pyuvq);
pmaeq->y = pyuvq->addr;
pmaeq->u = (PUINT32)((UINT32)pmaeq->y + (pmaeq->encoded_picture_height*pmaeq->encoded_picture_linesize));
pmaeq->v = (PUINT32)((UINT32)pmaeq->u + (pmaeq->encoded_picture_height*pmaeq->encoded_picture_linesize)/4);
pmaeq->pyuvq = pyuvq;
#endif
DLCL_APPEND(MAEQ_T, &pmms->fe_proc, pmaeq);
pmms->state |= ENABLE_FE;
// tell the state machine this is the last frame
if (pmaeq->endframe_flag)
pmaeq->state_change |= DISABLE_FE;
#ifdef MAE_DUMP
sprintf(pmms->pDumpPtr->szDumpStr[pmms->pDumpPtr->numEntries++], "run_fe_hw: frame # %d\n",pmaeq->tnum);
#endif
update_anchor_frames();
// Now compute the reference pointers and config parameters for the frame.
compute_reg_values(pmaeq, 0,(pmaeq->picture_structure == BOTTOM_FIELD)?1:0);
// PROGRAM THE FRONT END REGISTERS
program_fe_regs(pmaeq, 0);
DPRINTF(MSG_FE, (TEXT("run_fe_hw: Exit \n")));
return TRUE;
}
void ring_fe_doorbell(void)
{
unsigned long rval;
rval = au_readl(MAEFE_DMADBELL);
//DPRINTF(MSG_FE, (TEXT("ring_fe_doorbell: rval %x\n"), rval));
au_writel(MAEFE_DMADBELL_DB, MAEFE_DMADBELL);
rval = 1;
}
unsigned char discard_fe(void)
{
PMAEQ_T pmaeq;
PYUVQ_T pyuvq;
//DPRINTF(MSG_FUNCTION, (TEXT("discard_fe() entry\n")));
// if there is no source to discard then bail
if (!(pmms->fe_proc)) {
return FALSE;
}
// move the FE element to be the BE queue
DLCL_POP(MAEQ_T, &pmms->fe_proc, pmaeq);
// free the yuv buffer
if (pmms->yuv_inuse)
{
DLCL_POP(YUVQ_T, &pmms->yuv_inuse, pyuvq);
pyuvq->addr = pmaeq->y;
//DPRINTF(MSG_FE, (TEXT("YUV addr: 0x%x\n"),(UINT32)(pyuvq->addr)));
DLCL_APPEND(YUVQ_T, &pmms->yuv_free, pyuvq);
}
DLCL_APPEND(MAEQ_T, &pmms->maeq_free, pmaeq);
return TRUE;
}
UINT32 init_yuvq_list(void)
{
UINT32 i=0;
PYUVQ_T el;
UINT32 queue_addr = KRNL_YUVQ;
UINT32 yuv_buffer_addr = KRNL_YUV_FRAMES_BASE;
//DPRINTF(MSG_FUNCTION, (TEXT("init_yuvq_list entry\n")));
pmms->yuv_region_offset = yuv_buffer_addr - (UINT32)pmms;
// create free list
while (i<NUM_YUVQ_ELEMENTS)
{
el = (PYUVQ_T)queue_addr;
el->addr = (PUINT32)yuv_buffer_addr;
gYUVTable[i].pyuvq = el;
DPRINTF(MSG_INIT, (TEXT("init_yuvq_list YUV buffer %d address: %x\n"),(i+1),(UINT32)el->addr));
DLCL_APPEND(YUVQ_T, &pmms->yuv_free, el);
queue_addr += sizeof(YUVQ_T);
yuv_buffer_addr += SIZE_YUV_FRAME;
i++;
}
return 0;
}
void release_buffer_memory(PMAEQ_T el)
{
// move the consumption ptr to the end of this allocated block
pmms->inuse_bufferbase = (PUINT32)((UINT32)el->buffer + (UINT32)DEFAULT_BUFSIZE);
}
#ifndef MAE_HW
PUINT32 release_extra_info_memory(PMAEQ_T el)
{
// move the consumption ptr to the end of this allocated block
pmms->extra_info_inuse_base = el->extra_info + el->extra_info_size;
return 0;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -