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

📄 tmvld.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    
    UInt32      hfr = pictinfo->hForwRSize;
    UInt32      hbr = pictinfo->hBackRSize;
    UInt32      vfr = pictinfo->vForwRSize;
    UInt32      vbr = pictinfo->vBackRSize;

    tmAssert((instance >= 0 && instance < VLD_MAX_INSTANCES), TMLIBDEV_ERR_NOT_OWNER);

    field->dmvFlag     = (UInt8) vldExtractOUT_DMV     (mbhWord[0]);
    field->mvFormat    = (UInt8) vldExtractOUT_MVFORM  (mbhWord[0]);
    field->mvCount     = (UInt8) vldExtractOUT_MVCOUNT (mbhWord[0]);
    field->dctType     = (UInt8) vldExtractOUT_DCTTYPE (mbhWord[0]);
    field->motionType  = (UInt8) vldExtractOUT_MOTTYPE (mbhWord[0]);
    field->mbType      = (UInt8) vldExtractOUT_MBTYPE  (mbhWord[0]);
    field->mbAddrIncr  = (UInt8) vldExtractOUT_MBAINC  (mbhWord[0]);
    field->mbEscapeCnt = (UInt8) vldExtractOUT_ESCCT   (mbhWord[0]);

    if (VldInfo[instance].mpeg2Mode == 0) {
        field->quantScaleCode = (UInt8) vldExtractOUT1_QS  (mbhWord[3]);
        field->cbp            = (UInt8) vldExtractOUT1_CBP (mbhWord[3]);
        vldGetMotionVector(mv[0].forw, mbhWord[1], hfr, vfr);
        vldGetMotionVector(mv[0].back, mbhWord[2], hbr, vbr);
    }
    else {
        field->quantScaleCode = (UInt8) vldExtractOUT1_QS   (mbhWord[5]);
        field->cbp            = (UInt8) vldExtractOUT1_CBP  (mbhWord[5]);
        field->dmVector[0]    = (UInt8) vldExtractOUT1_DMV0 (mbhWord[5]);
        field->dmVector[1]    = (UInt8) vldExtractOUT1_DMV1 (mbhWord[5]);
        vldGetMotionVector(mv[0].forw, mbhWord[1], hfr, vfr);
        vldGetMotionVector(mv[0].back, mbhWord[3], hbr, vbr);
        vldGetMotionVector(mv[1].forw, mbhWord[2], hfr, vfr);
        vldGetMotionVector(mv[1].back, mbhWord[4], hbr, vbr);
    }
    return TMLIBDEV_OK;
}



/****************************************************************************
    tmLibdevErr_t vldSaveContext(Int instance, Int offset)
 
    saves context of a VLD instance.
    (8-offset) indicates the number of bits to shift to get to the byte boundary.

    saving context
      - save registers
      - turn off interrupt before flushing out input FIFO
      - shift out (8-offset) bits, make a byte by prepending it 
	with offset bits of 1's.  We need to prepend with 1's to avoid
	accidental startcode.
      - shift 8 bits at a time until VLD empty.
	8 bits since all we know is that FIFO is aligned to byte boundary
      - At this point, (VLD empty) VLD shift register content is
	not correct.   Ack, then give some count to make it correct.
	Read out the last 16 bits.
      - If the saved FIFO content is odd number of bytes, VLD
	does not function correctly when we restore the content.
	Make it even by prepending with 0xff.
      - FIFO save area should start at 64 byte boundary for easy 
	copyback (at restoration) and it should be larger than 66 bytes.
        (64 bytes + 2 byte shift register)
****************************************************************************/
tmLibdevErr_t
vldSaveContext(Int instance, Int offset)
{
    UInt32 data;
    Int numBytes;
    vldContext_t *vldContext = &VldInfo[instance].vldContext;
    UInt8 *fifo = vldContext->fifo;
    Int status;
    Int done;
    Int bitsLeft = 8 - offset;
    
    tmAssert((instance >= 0 && instance < VLD_MAX_INSTANCES), TMLIBDEV_ERR_NOT_OWNER);
    tmAssert(offset <= 8, VLD_ERR_WRONG_OFFSET);
    
    /*
     * Before getting anything from VLD, record the context
     */
    vldContext->control = vldGetCTL();
    vldContext->imask = vldGetIMASK();
    vldContext->offset = offset;
    vldContext->inputAddr = vldGetBIT_ADR();
    vldContext->inputCnt = vldGetBIT_CNT();
     
    /*
     * Turn off interrupt from VLD after saving imask,
     * no more input from the source
     */
    vldSetIMASK(0);
    vldSetBIT_CNT(0);

    /*
     * Flushing out FIFO.
     * First, store the partial byte with 1's prepended to avoid
     * accidental startcode.
     */
    data = (0xff << bitsLeft) | (vldGetSR_VALUE() >> (16 - bitsLeft));
    fifo[0] = (UInt8) data;
    numBytes = 1;

    /*
     * We make the shift register aligned to a byte boundary
     */
    vldSetCOMMAND(VLD_COMMAND_SHIFT | bitsLeft);
    
    status = vldGetSTATUS();
    done = 0;
    while ( done == 0)
    {
	if (status & VLD_STATUS_ERROR)
	{
	    return VLD_ERR_SAVING_CONTEXT_ERROR;
	}
	else if (status & VLD_STATUS_SUCCESS)
	{
	    /*
	     * Save next byte and shift
	     */
	    fifo[numBytes++] = (UInt8) (vldGetSR_VALUE() >> 8);
	    vldSetCOMMAND(VLD_COMMAND_SHIFT | 8);
	    status = vldGetSTATUS();
	}
	else if (status & VLD_STATUS_DMA_IN_DONE)
	{
	    /*
	     * We hit the end of the FIFO.   At this point, shift register
	     * does not contain the right content even if FIFO has the content.
	     * Shift register contains right content when we supply more
	     * data to VLD. (any garbage data)
	     * acknowledge, give more data, then read two bytes from shift
	     * register.   We are done flushing out input FIFO.
	     */
	    vldAckSTATUS_DMA_IN_DONE();
	    vldSetBIT_CNT(16);
            /*
	     * Wait until the previous shift succeeds
	     */
            while ( ! vldCheckSTATUS_SUCCESS())  ;
	    fifo[numBytes++] = (UInt8) (vldGetSR_VALUE() >> 8);
	    fifo[numBytes++] = (UInt8) (vldGetSR_VALUE() & 0xff);
	    
	    done = 1;
	}
	else
	{
	    /*
	     * None of the above bits is set.   Ignore startcode detection.
	     */
	    if (status & VLD_STATUS_STARTCODE)  vldAckSTATUS_STARTCODE();
	    status = vldGetSTATUS();
	}
    }
    
    vldContext->fifoLength = numBytes;

    /*
     * If odd number of bytes, make it even
     * ref: VLSI bug #21435
     */
    if (numBytes & 0x1)
    {
	Int i;
	
	for (i = numBytes; i > 0; i--)
	{
	    fifo[i] = fifo[i-1];
	}
	fifo[0] = 0xff;
	vldContext->offset += 8;
	vldContext->fifoLength ++;
    }
    
    return TMLIBDEV_OK;
}



/****************************************************************************
    tmLibdevErr_t vldRestoreContext(Int instance)
 
    Restore VLD context saved in VldInfo[instance].vldContext.
  
    restoring context
      - reset VLD.
	We need to reset since we will be dealing with different bit stream.
      - restore interrupt parameters.
      - replace interrupt handler if the saved VLD_BIT_CNT is not zero.
      - restore registers.
	  VLD_BIT_ADR <- addr of FIFO content saved area
	  VLD_BIT_CNT <- byte count (even) of FIFO content saved area
      - copyback
      - shift by offset
	This fills in input FIFO with saved content.
****************************************************************************/
tmLibdevErr_t
vldRestoreContext(Int instance)
{
    vldContext_t *vldContext = &VldInfo[instance].vldContext;
    vldInstanceSetup_t *vldSetup = &VldInfo[instance].vldSetup;
    intInstanceSetup_t setup;
    
    tmAssert((instance >= 0 && instance < VLD_MAX_INSTANCES), TMLIBDEV_ERR_NOT_OWNER);
    

    /*
     * First of all, reset internal states of VLD
     */
    RETURN_IF_NOT_OK(vldReset(instance));

    /*
     * Restore interrupt parameters
     */
    setup.enabled = True;
    setup.handler = vldSetup->vldISR;
    setup.priority = vldSetup->priority;
    setup.level_triggered = True;
    RETURN_IF_NOT_OK(intInstanceSetup(intVLD, &setup));

    /*
     * This global should be set before vldIntHandlerRestoreContext is invoked
     */
    VldCurInstance = instance;
    
    /*
     * If saved inputCnt is not zero, we need to replace the interrupt 
     * handler.   When it is zero, all the contents are in saved fifo.
     */
    if (vldContext->inputCnt != 0)
    {
	/*
	 * Directly replace interrupt handler
	 */
	MMIO(INTVEC14) = (UInt32) vldIntHandlerRestoreContext;
    }
    
    /*
     * enable interrupt.
     */
    vldSetIMASK(VldInfo[instance].vldSetup.interrupts);
    
    vldSetCTL(vldContext->control);
    vldSetIMASK(vldContext->imask);
    vldSetBIT_ADR((UInt32)vldContext->fifo);
    vldSetBIT_CNT(vldContext->fifoLength);

    _cache_copyback(vldContext->fifo, 128);
    

    /*
     * This fills in input FIFO with saved content
     */
    vldSetCOMMAND(VLD_COMMAND_SHIFT | vldContext->offset);
    
    return TMLIBDEV_OK;
}



/****************************************************************************
    static void vldIntHandlerRestoreContext(void)
    
    Interrupt handler used while restoring VLD context.
    Interrupt will occur when saved VLD input fifo is loaded.
    (since the length of it is less than 64 bytes, interrupt
    occurs at the moment we give the first command)
****************************************************************************/
static void vldIntHandlerRestoreContext(void)
{
#pragma TCS_handler

    Int status;
    Int instance = VldCurInstance;
    
    AppModel_suspend_scheduling();

    /*
     * Replace interrupt handler to the normal one
     */
    MMIO(INTVEC14) = (UInt32) VldInfo[instance].vldSetup.vldISR;
    
    status = vldGetSTATUS();
    

    if (status & VLD_STATUS_DMA_IN_DONE)
    {
	/*
	 * Acknowledge and give the saved data
	 */
	vldAckSTATUS_DMA_IN_DONE();
	vldSetBIT_ADR(VldInfo[instance].vldContext.inputAddr);
	vldSetBIT_CNT(VldInfo[instance].vldContext.inputCnt);
    }

    AppModel_resume_scheduling();
}



/****************************************************************************
    static int getNextInstance(void)

    Return the next instance id.
    Find the first unused instance.   If all are used, return a number
    out of range.   Caller should check the result against valid range.
****************************************************************************/
static int getNextInstance(void)
{
    Int i;
    
    for (i = 0; i < VLD_MAX_INSTANCES; i++)
    {
	if (VldInfo[i].used == 0)
	{
	    break;
	}
    }
    
    return i;
}

⌨️ 快捷键说明

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