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

📄 vidinj.c

📁 ST5100 driver files for ST chipset
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************
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 + -