📄 vidinj.c
字号:
/************************************************************************
COPYRIGHT (C) STMicroelectronics 2004
File name : vidinj.c
Description : Definition of video memory injection procedures
*
************************************************************************/
/*#######################################################################*/
/*########################## INCLUDES FILE ##############################*/
/*#######################################################################*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ostime.h>
#include "stddefs.h"
#include "stdevice.h"
#include "debug.h"
#include "sttbx.h"
#include "stsys.h"
#include "vidinj.h"
#include "app_data.h"
#ifdef TRACE_UART
#include "trace.h"
#endif
/* --- Global variables ------------------------------------------------ */
static task_t *VIDTid = NULL;
static U8 gInjectLevel = 100;
/* To lock injection task on underflow events */
semaphore_t VidMemInjection;
VID_Injection_t VID_Injection[VIDEO_MAX_DEVICE];
typedef struct
{
void* AllocatedBuffer_p;
void* AlignedBuffer_p;
ST_Partition_t* Partition_p;
U32 NbBytes;
U8 UsedCounter;
char StreamName[VID_MAX_STREAM_NAME];
} VID_BufferLoad_t;
VID_BufferLoad_t VID_BufferLoad[VID_MAX_BUFFER_LOAD]; /* address of stream buffer */
static U8 vid_DummyRead;
/*#######################################################################*/
/* INTERFACE OBJECT - LINK INJECTION TO VIDEO */
/*#######################################################################*/
ST_ErrorCode_t GetWriteAddress(void * const Handle, void ** const Address_p)
{
/* registered handle = index in cd-fifo array */
* Address_p = VID_Injection[(U32)Handle].Write_p;
return(ST_NO_ERROR);
}
void InformReadAddress(void * const Handle, void * const Address)
{
/* registered handle = index in cd-fifo array */
VID_Injection[(U32)Handle].Read_p = Address;
}
/*#######################################################################*/
/*-------------------------------------------------------------------------
* Function : VID_PrepareInjection
* Prepare for memory injection
* Input :
* Parameter:
* Output :
* Return :
* ----------------------------------------------------------------------*/
void VID_PrepareInjection(void)
{
U32 i;
/* Memory injection management : */
memset(VID_Injection, 0, sizeof(VID_Injection));
/* Init for injection process */
semaphore_init_fifo(&VidMemInjection, 0);
for (i=0;i<VIDEO_MAX_DEVICE;i++)
{
semaphore_init_fifo(&VID_Injection[i].Access, 1);
/* Common default values */
VID_Injection[i].Type = NO_INJECTION;
VID_Injection[i].State = STATE_INJECTION_NORMAL;
VID_Injection[i].Address = 0; /* no cd fifo in 5100: input-buffer is used instead */
VID_Injection[i].BitBufferSize = 0;
/* First is video and cdfifo number is i+1 */
VID_Injection[i].Number = i+1;
}
/* Init fields for BufferLoad */
for (i=0;i<VID_MAX_BUFFER_LOAD;i++)
{
VID_BufferLoad[i].AllocatedBuffer_p = NULL;
VID_BufferLoad[i].UsedCounter = 0;
}
}
/*-------------------------------------------------------------------------
* Function : VID_ReportInjectionAlreadyOccurs
* Common report function
* Input : Injection type
* Parameter:
* Output : TRUE if ok
* Return : TRUE if error, FALSE if success
* ----------------------------------------------------------------------*/
void VID_ReportInjectionAlreadyOccurs(U32 CDFifoNb)
{
switch(VID_Injection[CDFifoNb-1].Type)
{
case VID_HDD_INJECTION:
STTBX_Print(("Injection from hdd is already runnning on fifo %d!!\n", CDFifoNb));
break;
case VID_LIVE_INJECTION:
STTBX_Print(("Injection from live is already runnning on fifo %d!!\n", CDFifoNb));
break;
case VID_MEMORY_INJECTION:
STTBX_Print(("Injection from memory is already runnning on fifo %d!!\n", CDFifoNb));
break;
default:
STTBX_Print(("Injection is not yet described on this cd fifo %d!!\n", CDFifoNb));
break;
}
return;
}
/*-------------------------------------------------------------------------
* Function : VID_StopMemInject
* Stop memory injection
* Input : U32 VID_InjectionId
* Parameter:
* Output :
* Return : ST_ErrorCode_t ErrCode
* ----------------------------------------------------------------------*/
ST_ErrorCode_t VID_StopMemInject(U32 VID_InjectionId)
{
ST_ErrorCode_t ErrCode = ST_NO_ERROR;
if ( VID_InjectionId >= VIDEO_MAX_DEVICE )
{
STTBX_Print(("Invalid video injection identifier\n"));
return(ST_ERROR_BAD_PARAMETER);
}
if (VIDTid != NULL )
{
if ( VID_Injection[VID_InjectionId].Type == VID_MEMORY_INJECTION)
{
/* Lock access */
semaphore_wait(&VID_Injection[VID_InjectionId].Access);
/* Disable the injection flag */
VID_Injection[VID_InjectionId].Type = NO_INJECTION;
/* Unsubscribe to the underflow event */
/* Video Load Buffer in use */
VID_BufferLoad[VID_Injection[VID_InjectionId].Config.Memory.LoadBufferNb-1].UsedCounter--;
/* Free access */
semaphore_signal(&VID_Injection[VID_InjectionId].Access);
STTBX_Print(("VID_StopMemInjection: %d loops performed on CD fifo %d\n",
VID_Injection[VID_InjectionId].Config.Memory.LoopNbrDone, VID_InjectionId+1));
}
else
{
STTBX_Print(("VID_StopMemInject : Memory injection on CD fifo %d already stopped\n", VID_InjectionId+1));
return(ST_ERROR_BAD_PARAMETER);
}
}
else
{
/* VIDDecodeFromMemory() has finished to inject once */
VID_BufferLoad[VID_Injection[VID_InjectionId].Config.Memory.LoadBufferNb-1].UsedCounter--;
VID_Injection[VID_InjectionId].Type = NO_INJECTION;
/* Force end of DoVideoInject() */
semaphore_signal(&VidMemInjection);
}
return(ErrCode);
}
/*-------------------------------------------------------------------------
* Function : DoVideoInject
* Function is called by subtask
* Input :
* Parameter:
* Output : TRUE if ok
* Return : TRUE if error, FALSE if success
* ----------------------------------------------------------------------*/
static void DoVideoInject( void )
{
U32 VID_InjectionId=0;
U32 DelayAfterJob = 10;
VID_MemInjection_t *PtiMemInjectVID_Injection_p;
U32 DmaTransferSize;
U32 InputBufferFreeSize;
U32 SnapInputRead,SnapInputWrite;
ST_ErrorCode_t ErrCode = ST_NO_ERROR;
BOOL DoJob;
U32 BitBufferSize, BitBufferThreshold, BitBufferFreeSize;
U32 MaxDmaTransferSize = 128*1024;
U32 RemainingSourceDataSize = 0;
while (1)
{
/* Wait the event UNDERFLOW coming from VIDEO */
semaphore_wait(&VidMemInjection);
/* Search for an injection job */
for (VID_InjectionId=0; VID_InjectionId<VIDEO_MAX_DEVICE; VID_InjectionId++)
{
DoJob=FALSE;
if (VID_Injection[VID_InjectionId].Type == VID_MEMORY_INJECTION)
{
if ( VID_Injection[VID_InjectionId].Config.Memory.JobNumberOverflow )
{
STTBX_Print(("Jobs list overflow for cd fifo %d !!! Stop memory injection.\n", VID_InjectionId+1));
(void)VID_StopMemInject(VID_InjectionId);
}
else
{
if ( VID_Injection[VID_InjectionId].Config.Memory.SynchronizedByUnderflowEvent )
{
/* Need a job to launch injection */
if (VID_Injection[VID_InjectionId].Config.Memory.JobReadIndex
!= VID_Injection[VID_InjectionId].Config.Memory.JobWriteIndex)
{
DoJob=TRUE;
}
}
else
{
/* Enabled is enough to launch injection */
DoJob=TRUE;
}
}
}
if (!(DoJob))
{
continue; /* direct take next index in 'for' loop */
}
/* --> DoJob = TRUE so we inject a piece of memory in this VID_InjectionId */
if(VID_Injection[VID_InjectionId].State == STATE_INJECTION_NORMAL)
{
PtiMemInjectVID_Injection_p = &VID_Injection[VID_InjectionId].Config.Memory;
if ( PtiMemInjectVID_Injection_p->SynchronizedByUnderflowEvent )
{
PtiMemInjectVID_Injection_p->JobReadIndex = (PtiMemInjectVID_Injection_p->JobReadIndex+1) % VID_MEMINJECT_MAXJOBNUMBER;
DmaTransferSize = PtiMemInjectVID_Injection_p->Jobs[PtiMemInjectVID_Injection_p->JobReadIndex].RequestedSize;
}
else
{
ErrCode = STVID_GetBitBufferFreeSize(VID_Injection[VID_InjectionId].Driver.Handle, &BitBufferFreeSize);
if (ErrCode != ST_NO_ERROR)
{
STTBX_Print(( "DoVideoInject() : error STVID_GetBitBufferFreeSize()=0x%x !!\n", ErrCode));
(void)VID_StopMemInject(VID_InjectionId);
}
BitBufferSize = VID_Injection[VID_InjectionId].BitBufferSize;
/* Get the DMA transfert size */
if ( PtiMemInjectVID_Injection_p->SynchronizedByUnderflowEvent )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -