📄 vidinj.c
字号:
/* Lock injection access */
semaphore_wait(&VID_Injection[VID_InjectionId].Access);
PtiMemInjectVID_Injection_p->JobReadIndex = (PtiMemInjectVID_Injection_p->JobReadIndex+1) % VID_MEMINJECT_MAXJOBNUMBER;
DmaTransferSize = PtiMemInjectVID_Injection_p->Jobs[PtiMemInjectVID_Injection_p->JobReadIndex].RequestedSize;
/* Free injection access */
semaphore_signal(&VID_Injection[VID_InjectionId].Access);
if (DmaTransferSize > BitBufferFreeSize)
{
DmaTransferSize = BitBufferFreeSize;
}
}
else
{
DmaTransferSize = BitBufferFreeSize;
/* Compute threshold to avoid an overflow */
BitBufferThreshold = (3*BitBufferSize/4) & (~3);
BitBufferThreshold = ((U32) gInjectLevel * BitBufferThreshold)/ (U32) 100;
/* prevent for data pending in input-buffer */
if(BitBufferThreshold > ( (U32)VID_Injection[VID_InjectionId].Top_p
-(U32)VID_Injection[VID_InjectionId].Base_p+1))
{
BitBufferThreshold = BitBufferThreshold
-( (U32)VID_Injection[VID_InjectionId].Top_p
-(U32)VID_Injection[VID_InjectionId].Base_p+1);
}
if (BitBufferSize-BitBufferFreeSize > BitBufferThreshold)
{
DmaTransferSize = 0;
task_reschedule();
}
else
{
DmaTransferSize = BitBufferThreshold-(BitBufferSize-BitBufferFreeSize);
}
}
/* Control data size to be injected */
/* - enough data to fill the bit buffer until Threshold limit */
/* - 128k bytes maximum */
/* - remaining source data maximum */
RemainingSourceDataSize = (U32)PtiMemInjectVID_Injection_p->SrcSize -
(U32)(PtiMemInjectVID_Injection_p->CurrentSrcPtr_p - PtiMemInjectVID_Injection_p->SrcBuffer_p);
if (DmaTransferSize > MaxDmaTransferSize)
DmaTransferSize = MaxDmaTransferSize;
if (DmaTransferSize > RemainingSourceDataSize)
DmaTransferSize = RemainingSourceDataSize;
if (DmaTransferSize > 0)
{
SnapInputRead = (U32)VID_Injection[VID_InjectionId].Read_p;
SnapInputWrite = (U32)VID_Injection[VID_InjectionId].Write_p;
if(SnapInputWrite < SnapInputRead)
{
InputBufferFreeSize = SnapInputRead
- SnapInputWrite
- 10; /* -10 to leave 10 bytes empty to avoid
* considering a full buffer(Read=Write) as empty */
}
else
{
InputBufferFreeSize = (U32)VID_Injection[VID_InjectionId].Top_p
-SnapInputWrite+1;
}
if(DmaTransferSize > InputBufferFreeSize)
{
DmaTransferSize = InputBufferFreeSize;
}
if(DmaTransferSize > 0x4000)
{
DmaTransferSize=0x4000;
}
if( (SnapInputWrite + DmaTransferSize >= (U32)VID_Injection[VID_InjectionId].Top_p) &&
(SnapInputRead == (U32)VID_Injection[VID_InjectionId].Base_p) )
{
DmaTransferSize -= 1; /* Leave 1 byte empty to avoid considering a full buffer(Read=Write)
* as empty */
}
memcpy(/* dest */(void*)SnapInputWrite,
/* src */ PtiMemInjectVID_Injection_p->CurrentSrcPtr_p,
DmaTransferSize);
/* Push the W pointer in video input */
if(( SnapInputWrite+ DmaTransferSize) > (U32)VID_Injection[VID_InjectionId].Top_p)
{
SnapInputWrite= (U32)VID_Injection[VID_InjectionId].Base_p;
}
else
{
SnapInputWrite= SnapInputWrite + DmaTransferSize;
}
/* Share the new input ptr */
VID_Injection[(U32)VID_InjectionId].Write_p = (void*)SnapInputWrite;
}
/* EnableDelayAfterDMA */
task_delay((30*(U32)DmaTransferSize/1024)/8);
/* Lock injection access */
semaphore_wait(&VID_Injection[VID_InjectionId].Access);
/* Increment the source pointer */
PtiMemInjectVID_Injection_p->CurrentSrcPtr_p += DmaTransferSize;
/* Check if the whole buffer has been sent */
if(PtiMemInjectVID_Injection_p->CurrentSrcPtr_p
> (PtiMemInjectVID_Injection_p->SrcBuffer_p
+ (U32)PtiMemInjectVID_Injection_p->SrcSize)
- 1)
{
/* Reset the current source pointer */
PtiMemInjectVID_Injection_p->CurrentSrcPtr_p = PtiMemInjectVID_Injection_p->SrcBuffer_p;
/* Decrement the loop counter */
if (PtiMemInjectVID_Injection_p->LoopNbr != -1)
PtiMemInjectVID_Injection_p->LoopNbr--;
/* Anyway, increment achieved loop counter */
PtiMemInjectVID_Injection_p->LoopNbrDone++;
/* Check if CD fifo injection must be disabled */
if ( PtiMemInjectVID_Injection_p->LoopNbr == 0 )
{
/* Free injection access */
semaphore_signal(&VID_Injection[VID_InjectionId].Access);
(void)VID_StopMemInject(VID_InjectionId);
/* Lock injection access */
semaphore_wait(&VID_Injection[VID_InjectionId].Access);
}
}
/* Free injection access */
semaphore_signal(&VID_Injection[VID_InjectionId].Access);
} /* end if enabled */
/* EnableDelayAfterJob */
task_delay(DelayAfterJob);
if ( !PtiMemInjectVID_Injection_p->SynchronizedByUnderflowEvent &&
(VID_Injection[VID_InjectionId].Type == VID_MEMORY_INJECTION))
{
semaphore_signal(&VidMemInjection);
}
} /* end if STATE_INJECTION_NORMAL */
} /* for (MaxSearchVID_InjectionId=VIDEO_MAX_DEVICE;MaxSearchVID_InjectionId;MaxSearchVID_InjectionId--) */
} /* end of while */
} /* end of DoVideoInject() */
/*-------------------------------------------------------------------------
* Function : VID_MemInject
* Inject Video in Memory to DMA
* Input : STVID_Handle_t VidHandle, S32 FifoNb, S32 InjectLoop, S32 BufferNb
* Output :
* Return : ST_ErrorCode_t ErrCode
* ----------------------------------------------------------------------*/
ST_ErrorCode_t VID_MemInject(STVID_Handle_t VidHandle, S32 FifoNb, S32 InjectLoop, S32 BufferNb)
{
ST_ErrorCode_t ErrCode = ST_NO_ERROR;
void *Param = NULL;
U32 InputBuffersize, i;
if ((FifoNb < 1) || (FifoNb > VIDEO_MAX_DEVICE))
{
STTBX_Print(("Error occured: expected fifo number (1 to %d)\n", VIDEO_MAX_DEVICE));
return(ST_ERROR_BAD_PARAMETER);
}
if ((BufferNb < 1) || (BufferNb > VID_MAX_BUFFER_LOAD))
{
STTBX_Print(("Error occured: expected load buffer number (default is 1. max is %d)", VID_MAX_BUFFER_LOAD));
return(ST_ERROR_BAD_PARAMETER);
}
if(VID_BufferLoad[BufferNb-1].AllocatedBuffer_p == NULL)
{
STTBX_Print(( "No file loaded in memory buffer !!\n" ));
return(ST_ERROR_BAD_PARAMETER);
}
VID_Injection[FifoNb-1].Driver.Handle = VidHandle;
/* Lock injection access */
semaphore_wait(&VID_Injection[FifoNb-1].Access);
if(VID_Injection[FifoNb-1].BitBufferSize == 0)
{
/* No injection occured. Bit buffer should be empty */
ErrCode = STVID_GetBitBufferFreeSize(VID_Injection[FifoNb-1].Driver.Handle, &VID_Injection[FifoNb-1].BitBufferSize);
if(ErrCode != ST_NO_ERROR)
{
VID_Injection[FifoNb-1].BitBufferSize = 0;
STTBX_Print(("Error occured while exec GetBitBufferFreeSize = %d\n", ErrCode));
return(ErrCode);
}
}
if(VID_Injection[FifoNb-1].Type == NO_INJECTION)
{
if(VIDTid == NULL)
{
VIDTid = task_create( (void (*)(void *))DoVideoInject, Param, 4096,
VID_INJECTION_TASK_PRIORITY, "VideoInject", (task_flags_t)0 );
if ( VIDTid == NULL )
{
STTBX_Print(("Unable to create video task\n"));
return(ST_ERROR_BAD_PARAMETER);
}
else
{
if(InjectLoop < 0)
{
STTBX_Print(("Infinite playing on fifo %d\n", FifoNb));
}
else
{
STTBX_Print(("Playing video %d times on fifo %d\n", InjectLoop, FifoNb ));
}
}
}
VID_Injection[FifoNb-1].Config.Memory.SrcBuffer_p = VID_BufferLoad[BufferNb-1].AlignedBuffer_p;
VID_Injection[FifoNb-1].Config.Memory.CurrentSrcPtr_p = VID_BufferLoad[BufferNb-1].AlignedBuffer_p;
VID_Injection[FifoNb-1].Config.Memory.SrcSize = VID_BufferLoad[BufferNb-1].NbBytes;
VID_Injection[FifoNb-1].Config.Memory.LoadBufferNb = BufferNb;
VID_Injection[FifoNb-1].Config.Memory.LoopNbr = InjectLoop;
VID_Injection[FifoNb-1].Config.Memory.LoopNbrDone = 0;
VID_Injection[FifoNb-1].Config.Memory.SynchronizedByUnderflowEvent = FALSE;
for (i = 0; i < VID_INJECTEDSIZEHISTORYSIZE; i++)
{
VID_Injection[FifoNb-1].Config.Memory.InjectedSizeHistory[i] = VID_INVALID_INJECTEDSIZE;
}
VID_Injection[FifoNb-1].Config.Memory.InjectedSizeHistoryIndex = 0;
/* Get Input buffer characteristics */
ErrCode = STVID_GetDataInputBufferParams(VID_Injection[FifoNb-1].Driver.Handle,
&VID_Injection[FifoNb-1].Base_p, &InputBuffersize);
/* Update injection pointer. */
VID_Injection[FifoNb-1].Top_p =
(void *)((U32)VID_Injection[FifoNb-1].Base_p + InputBuffersize - 1);
/* Test if it's the first use of injection. */
if (VID_Injection[FifoNb-1].Write_p == NULL)
{
/* Affect default values to Read/Write pointers. */
VID_Injection[FifoNb-1].Write_p = VID_Injection[FifoNb-1].Base_p;
VID_Injection[FifoNb-1].Read_p = VID_Injection[FifoNb-1].Base_p;
}
else
{
/* This injecter was already used. Test previous write pointer position. */
if ( ((U32)VID_Injection[FifoNb-1].Write_p > (U32)VID_Injection[FifoNb-1].Top_p) ||
((U32)VID_Injection[FifoNb-1].Write_p < (U32)VID_Injection[FifoNb-1].Base_p) )
{
/* This injecter was probably used with an other video instance. */
/* Take write pointer to input buffer base address. */
VID_Injection[FifoNb-1].Write_p = VID_Injection[FifoNb-1].Base_p;;
}
VID_Injection[FifoNb-1].Read_p = VID_Injection[FifoNb-1].Write_p;
}
/* Configure the interface-object */
ErrCode = STVID_SetDataInputInterface( VID_Injection[FifoNb-1].Driver.Handle,
GetWriteAddress,InformReadAddress,(void*)(FifoNb-1));
VID_Injection[FifoNb-1].Type = VID_MEMORY_INJECTION;
/* Launch injection */
semaphore_signal(&VidMemInjection);
/* Video Load Buffer in use */
VID_BufferLoad[BufferNb-1].UsedCounter++;
}
else
{
VID_ReportInjectionAlreadyOccurs(FifoNb);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -