📄 tmvld.c
字号:
/*
* 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 + -