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

📄 tmvld.c

📁 用于TM1300/PNX1300系列DSP(主要用于视频处理)的设备库的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (c) 1995-1999 by TriMedia Technologies. 
 *
 * +------------------------------------------------------------------+
 * | This software is furnished under a license and may only be used  |
 * | and copied in accordance with the terms and conditions of  such  |
 * | a license and with the inclusion of this copyright notice. This  |
 * | software or any other copies of this software may not be provided|
 * | or otherwise made available to any other person.  The ownership  |
 * | and title of this software is not transferred.                   |
 * |                                                                  |
 * | The information in this software is subject  to change without   |
 * | any  prior notice and should not be construed as a commitment by |
 * | TriMedia Technologies.                                           |
 * |                                                                  |
 * | this code and information is provided "as is" without any        |
 * | warranty of any kind, either expressed or implied, including but |
 * | not limited to the implied warranties of merchantability and/or  |
 * | fitness for any particular purpose.                              |
 * +------------------------------------------------------------------+
 *
 *  Module name              : tmVLD.c  1.24       
 *
 *  Last update              : 19:47:55 - 00/11/09 
 *
 *  Description              :
 *
 *    Behavioral description of Hardware VLD (HVLD) unit.
 *
 * VLD sharing:
 * 
 *    This module provides functions to be used in sharing VLD for
 *    multiple input streams.   (saveVLDContext/restoreVLDContext)
 *    The means for actual sharing (semaphore, queue, etc.) and granularity 
 *    of sharing (frame boundary, slice boundary, etc.) are all outside the
 *    scope of this module.
 *
 *    Because of the hardware limitation, saveVLDContext needs to know 
 *    how many bits are consumed from the nearest byte boundary.
 *    This means that VLD context switch should be done at a position where
 *    the bit offset from a byte boundary is precisely known.
 *
 *    VLD sharing can be done between widely varying streams.   It can be
 *    done between MPEG-1 and MPEG-2 streams with different parameters
 *    provided in vldInstanceSetup_t structure. (ISR, priority, etc.)
 */

#include <tm1/tmVLD.h>
#include <tm1/tmAssert.h>
#include <tmlib/AppModel.h>
#include <tmlib/tmlibc.h>
#include <tmlib/dprintf.h>
#include <tm1/tmProcessor.h>
#include <string.h>

/* normally, these come from the Makefile */
#ifndef MAJOR_VERSION
#define MAJOR_VERSION   3
#endif
#ifndef MINOR_VERSION
#define MINOR_VERSION   0
#endif
#ifndef BUILD_VERSION
#define BUILD_VERSION   0
#endif

/*
 * Number of supported instances
 */
#define VLD_MAX_INSTANCES	6

/*
 * Local convenience
 */
#define RETURN_IF_NOT_OK(x) \
{ \
    tmLibdevErr_t status = (x); \
    if (status != TMLIBDEV_OK)  return status; \
}

/*
 * Exported global.
 * This should be accessed via macros vldSetEmptyFlag and vldGetEmptyFlag.
 * No need to store this in vldInstanceInfo_t since VldEmptyMode is never
 * true at vld context switch time.
 */
Bool        _VldEmptyMode = False;

/*
 * Local globals
 */
static Int               VldCurInstance;
static vldInstanceInfo_t VldInfo[VLD_MAX_INSTANCES];
static vldCapabilities_t Capabilities =
{
    {MAJOR_VERSION, MINOR_VERSION, BUILD_VERSION},   	/* version */
    VLD_MAX_INSTANCES,            			/* numSupportedInstances */
    0             					/* numCurrentInstances */
};

static Int getNextInstance(void);
static void vldIntHandlerRestoreContext(void);


static tmLibdevErr_t vldGetNumberOfUnits(UInt32 *pNumberOfUnits)
{
    tmLibdevErr_t err;
    pprocCapabilities_t procCap;
   
    /* Make sure we are running on a TM1 */
    err = procGetCapabilities(&procCap);
    if (err != TMLIBDEV_OK)
        return err; 
    switch(procCap->deviceID)
    {
    case PROC_DEVICE_TM1000:
    case PROC_DEVICE_TM1100:
    case PROC_DEVICE_TM1300:
        *pNumberOfUnits = 1;
        break;
    default:
    	*pNumberOfUnits = 0;
        break;    
    }
    return TMLIBDEV_OK;
}


/****************************************************************************
    tmLibdevErr_t vldGetCapabilities(pvldCapabilities_t *cap)

    Return capabilities
****************************************************************************/
tmLibdevErr_t 
vldGetCapabilities(pvldCapabilities_t * cap)
{
    UInt32              numberOfUnits;
    tmLibdevErr_t       err;

    if ((err = vldGetNumberOfUnits(&numberOfUnits)) != TMLIBDEV_OK)
        return err;
    if (numberOfUnits == 0)
        return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;

    *cap = &Capabilities;

    return TMLIBDEV_OK;
}



/****************************************************************************
    tmLibdevErr_t vldOpen(Int *instance)

    Open an instance.
    Id to the instance is returned in *instance.
    *instance contains -1 if failure.
    
    Need to be protected from simultaneous invocation.
****************************************************************************/
tmLibdevErr_t 
vldOpen(Int * instance)
{
    Int                 id;
    tmLibdevErr_t       err;
    UInt32              numberOfUnits;

    if ((err = vldGetNumberOfUnits(&numberOfUnits)) != TMLIBDEV_OK)
        return err; 
    if (numberOfUnits == 0)
        return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
 
    AppModel_suspend_scheduling();
    id = getNextInstance();
    
    if (id < 0 || id >= VLD_MAX_INSTANCES)
    {
	*instance = -1;
	AppModel_resume_scheduling();
	return TMLIBDEV_ERR_NO_MORE_INSTANCES;
    }
    
    *instance = id;
    memset(&VldInfo[id], 0, sizeof(vldInstanceInfo_t));
    VldInfo[id].used = 1;
    VldInfo[id].vldContext.fifo = (UInt8 *)
      ((((Int)(VldInfo[id].vldContext.fifoBuf)) + 63) & ~0x3f);
      
    Capabilities.numCurrentInstances++;
    
    AppModel_resume_scheduling();
    return TMLIBDEV_OK;
}



/****************************************************************************
    tmLibdevErr_t vldClose(Int instance)

    Shut down the device and deinstall interrupt
****************************************************************************/
tmLibdevErr_t 
vldClose(Int instance)
{
    tmLibdevErr_t err = TMLIBDEV_OK;
    intInstanceSetup_t setup;
    
    tmAssert((instance >= 0 && instance < VLD_MAX_INSTANCES), TMLIBDEV_ERR_NOT_OWNER);

    AppModel_suspend_scheduling();
    
    /*
     * de-install interrupt handler.
     * leave everything else intact.
     */
    if (VldInfo[instance].vldSetup.vldISR) {
	intGetInstanceSetup(intVLD, &setup);
        setup.handler = Null;
        intInstanceSetup(intVLD, &setup);
    }

    VldInfo[instance].used = 0;
    Capabilities.numCurrentInstances--;

    /*
     * Close interrupt only when no more user
     */
    if (Capabilities.numCurrentInstances == 0) {
	err = intClose(intINT_14);
        if (err != TMLIBDEV_OK) {
            goto vldCloseExit;
	}
    }

vldCloseExit:
    AppModel_resume_scheduling();
    return err;
}



/****************************************************************************
    tmLibdevErr_t vldInstanceSetup(Int instance, vldInstanceSetup_t *vldSetup)

    Function         : Validates the owner, fills the shift register,
               broad init and installs interrupt handler
    Parameters       : (I) owner instance and
               (I) vldInstanceSetup_t structure instance pointer
    Function Result  : zero on success and error code on failure
****************************************************************************/
tmLibdevErr_t 
vldInstanceSetup(Int instance, vldInstanceSetup_t * vldSetup)
{
    intInstanceSetup_t setup;

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

    vldReset(instance);        /* Reset VLD first of all  */

    /*
     * Record vldSetup into VldInfo
     */
    VldInfo[instance].vldSetup = *vldSetup;
    
    if (vldSetup->vldISR) {
	/* 
	 * install interrupt.
	 * Do not check the result since it may be opened already
	 */
	intOpen(intVLD);

	setup.enabled = True;
	setup.handler = vldSetup->vldISR;
	setup.priority = vldSetup->priority;
	setup.level_triggered = True;
	intInstanceSetup(intVLD, &setup);
    }

    /*
     * This is the current instance
     */
    VldCurInstance = instance;
    
    /*
     * enable interrupt.
     */
    vldSetIMASK(vldSetup->interrupts);

    return TMLIBDEV_OK;
}



/****************************************************************************
    tmLibdevErr_t vldCommand(Int instance, Int32 command)

    Issue a VLD command
    VLD_COMMAND_PARSE: asynchronous.  Returns right away
    All other commands: synchronous.  Returns when done.
****************************************************************************/
tmLibdevErr_t 
vldCommand(Int instance, Int32 command)
{
    UInt32      status;

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

    if (vldCOMMAND_PARSE(command)) { 
        tmAssert(vldCheckSTATUS_SUCCESS(), VLD_ERR_PREV_COMMAND_NOT_DONE);
    } 

    vldSetCOMMAND(command);

    if (! vldCOMMAND_PARSE(command)) {
        status = vldGetSTATUS();
	
        while (!(status & ( VLD_STATUS_SUCCESS | VLD_STATUS_ERROR 
                          | VLD_STATUS_STARTCODE ))) {
            if (vldGetEmptyFlag(instance) == True) {
                (*VldInfo[instance].vldSetup.vldEmptyFunc) (VldInfo[instance].vldSetup.vidStream, True);
                vldSetEmptyFlag(instance, False);
            }
            status = vldGetSTATUS();
        }

⌨️ 快捷键说明

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