📄 dr_prefetch.cpp
字号:
/*****************************************************************************
******************************************************************************
** **
** Copyright (c) 2005 Videon Central, Inc. **
** All rights reserved. **
** **
** The computer program contained herein contains proprietary information **
** which is the property of Videon Central, Inc. The program may be used **
** and/or copied only with the written permission of Videon Central, Inc. **
** or in accordance with the terms and conditions stipulated in the **
** agreement/contract under which the programs have been supplied. **
** **
******************************************************************************
*****************************************************************************/
/**
* @file dr_prefetch.cpp
*
* Prefetch class for the DR
*
* $Id: dr_prefetch.cpp,v 1.116 2007/01/05 01:59:29 rbehe Exp $
*/
#include <stdlib.h>
#include "vdvd_types.h"
#include "loader_app.h"
#include "dr_types.h"
#include "dr_prefetch.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
#define DR_TO_DISK 0
#if DR_TO_DISK
#include <fcntl.h>
int fdrout[4];
#include <stdio.h>
#include <unistd.h>
char drfilename[24] = "/mnt/hd/dr_stream";
#endif
#define DEBUG_DR_PREFETCH DBG_ERROR
#define DBG_ON(x) (DEBUG_DR_PREFETCH >= x)
OS_SEM_ID DRPrefetch::m_semDevice=0;
/**********************************************
*
* Implementations for DRPrefetch Base Class
*
**********************************************/
static ULONG PrefetchThreadCaller(PVOID pvParam)
{
DR_ERROR status = DR_FAILURE;
if (NULL != pvParam)
{
status = ( (DRPrefetch*)pvParam )->PrefetchThread();
}
OS_TaskExit();
return (status);
}
/**
* destroy - stops the prefetch task and deletes all allocated objects
*
* @retval none
*
* @remarks none.
*/
void DRPrefetch::destroy(void)
{
#if DR_TO_DISK
if (fdrout[m_idnum] > 0)
{
close(fdrout[m_idnum]);
}
#endif
/* if the thread is running (which it should be), stop and kill and delete it */
if (m_prefetchThreadID != 0)
{
/* Set the flag to kill it */
m_fKill = TRUE;
/* Abort() also clears and disables the queue */
Abort();
QueueControl(DR_QUEUE_CMD_ENABLE);
/* and wait for it to die */
DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d - idnum %u: Call OS_TaskJoin\n", __FILE__, __LINE__, m_idnum));
OS_TaskJoin(m_prefetchThreadID);
OS_TaskDelete(m_prefetchThreadID);
m_prefetchThreadID = 0;
DBGPRINT(DBG_ON(DBG_TRACE), ("%s, %d - idnum %u: Call OS_TaskJoin ... Completed\n", __FILE__, __LINE__, m_idnum));
}
/* delete the play block semaphore */
if (m_semPlayBlock != 0)
{
OS_SemDelete(m_semPlayBlock);
m_semPlayBlock = 0;
}
/* delete the queueEnabled semaphore */
if (m_semPlayQueueEnabled != 0)
{
OS_SemDelete(m_semPlayQueueEnabled);
m_semPlayQueueEnabled = 0;
}
/* delete the device semaphore */
if (m_semDevice != 0)
{
OS_SemDelete(m_semDevice);
m_semDevice = 0;
}
/* delete our play queue and associated allocations */
if (m_pPlayMessagePool)
{
OS_MemFree(m_pPlayMessagePool);
m_pPlayMessagePool = NULL;
}
if (m_prefetchPlayQueue != NULL)
{
m_prefetchPlayQueue->Destroy();
delete (m_prefetchPlayQueue);
m_prefetchPlayQueue = NULL;
}
m_prefetchStream = NULL;
}
/**
* Private function used to send a cStream packet to the PE.
*
* @param streamMessage - The message.
* @param pPayload - A payload to attach to the message.
*
* @retval DR_ERROR
*
*/
DR_ERROR DRPrefetch::drSendStream(DROUTPUTMESSAGE streamMessage, cPayload *pPayload)
{
DROUTPUTMESSAGE *pStreamMessage = NULL;
DR_ERROR status = DR_SUCCESS;
#if DR_TO_DISK
if (pPayload != NULL)
{
write( fdrout[m_idnum], pPayload->get_rd_ptr(), pPayload->get_size());
}
#endif
/* Get a stream message */
do
{
if (m_fAbort == TRUE)
{
status = DR_FAILURE;
break;
}
pStreamMessage = (DROUTPUTMESSAGE *)m_prefetchStream->GetMsg(OS_WAIT_1S/4); /* TODO: figure out how to do with a WAIT_FOREVER */
} while (pStreamMessage == NULL);
if (DR_SUCCESS == status)
{
/* Fill it with data */
*pStreamMessage = streamMessage;
pStreamMessage->Encryption = m_encryption_type;
/* reference the payload */
if (pPayload != NULL)
{
while (1)
{
pStreamMessage->payload = pPayload->REF_PAYLOAD;
if (pStreamMessage->payload != NULL)
{
break;
}
OS_TaskDelay(OS_WAIT_1S / 50);
}
}
else
{
pStreamMessage->payload = NULL;
}
DBGPRINT(DBG_ON(DBG_VERBOSE), ("DR output stream %u fullstatus(): %u\n", m_idnum, m_prefetchStream->FullStatus()));
/* Pass it along */
if (m_prefetchStream->Write((PVOID)pStreamMessage, OS_WAIT_FOREVER) != OS_OK)
{
DbgPrint(("%s, %d, drSendStream FAILED\n", __FILE__, __LINE__));
status = DR_FAILURE;
}
}
if (DR_SUCCESS != status)
{
if (NULL != pStreamMessage)
{
if (pStreamMessage->payload != NULL)
{
delete (pStreamMessage->payload);
pStreamMessage->payload = NULL;
}
m_prefetchStream->ReleaseMsg(pStreamMessage);
}
}
return (status);
}
/**
* Private function used to send a timing packet to the PE.
*
* @param bAppType - The application type.
* @param bTransCond - The transition condition (from the previous to the current).
* @param ulStartTime - The start time.
* @param ulStopTime - The stop time.
* @param pvContext - The context (can be null if not applicable).
*
* @retval DR_ERROR
*/
DR_ERROR DRPrefetch::drSendTimingInfo(BYTE bAppType, BYTE bTransCond, ULONG ulStartTime, ULONG ulStopTime, PVOID pvContext)
{
DROUTPUTMESSAGE streamMessage;
cPayload *pStreamPayload = NULL;
INFOPAYLOAD *infoPayload;
/* these are used */
streamMessage.fInfoPayload = TRUE;
streamMessage.StreamContext = pvContext;
/* Get a buffer from the stream */
pStreamPayload = drGetPayload();
if (pStreamPayload == NULL)
{
return(DR_FAILURE);
}
/* get the payload's write pointer */
infoPayload = (INFOPAYLOAD*)pStreamPayload->get_base_ptr();
/* set the type */
infoPayload->bType = INFOTYPE_TIMEPACK;
/* set the data */
infoPayload->time.bAppType = bAppType;
infoPayload->time.bTransCond = bTransCond;
infoPayload->time.ulStartTime = ulStartTime;
infoPayload->time.ulStopTime = ulStopTime;
/* transfer the payload to the PE */
drSendStream(streamMessage, pStreamPayload);
/* delete the payload */
delete pStreamPayload;
pStreamPayload = NULL;
return(DR_SUCCESS);
}
/**
* Configure - starts up the prefetch thread and allocates all member objects.
*
* @param prm_loader - the loader.
* @param prm_stream - the the output stream.
* @param prm_event - the event handler.
* @param prm_pContext - the context of the event handler.
*
* @retval none
*
* @remarks none.
*/
DR_ERROR DRPrefetch::Configure (LOADER_HANDLE prm_loader, cStream* prm_stream, DR_EVENT prm_event, PVOID prm_pContext)
{
if (m_loader != NULL)
{
DbgPrint(("DRPrefetch has already been Configured! Need to delete before reconfigure!\n"));
return(DR_INVALID_STATE);
}
m_prefetchStream = prm_stream;
m_loader = prm_loader;
m_event = prm_event;
m_pContext = prm_pContext;
m_fKill = FALSE;
m_fAbort = FALSE;
/* Create and initialize the data proc message queue */
m_prefetchPlayQueue = new cStream;
m_pPlayMessagePool = OS_MemAlloc(sizeof(PLAYMSG) * DR_PLAYQUEUE_DEPTH);
if ((m_prefetchPlayQueue == NULL) || (m_pPlayMessagePool == NULL))
{
DbgPrint(("DRCreate: Unable to create PlayQueue!\n"));
goto errout;
}
else
{
m_prefetchPlayQueue->Initialize(m_pPlayMessagePool, DR_PLAYQUEUE_DEPTH, sizeof(PLAYMSG), "DR_DATAQUEUE");
}
m_semPlayBlock = OS_SemBCreateNamed(OS_SEM_Q_FIFO, OS_SEM_EMPTY, "PlayBlock");
if (m_semPlayBlock == 0)
{
DbgPrint(("\nDRPrefetch: Unable to create DR semaphores!\n"));
goto errout;
}
m_semPlayQueueEnabled = OS_SemBCreateNamed(OS_SEM_Q_FIFO, OS_SEM_EMPTY, "PlayQueueEnabled");
if (m_semPlayQueueEnabled == 0)
{
DbgPrint(("\nDRPrefetch: Unable to create DR semaphores!\n"));
goto errout;
}
if (m_semDevice == 0)
{
m_semDevice = OS_SemBCreateNamed(OS_SEM_Q_FIFO, OS_SEM_FULL, "DeviceSemaphore");
}
if (m_semDevice == 0)
{
DbgPrint(("\nDRPrefetch: Unable to create DR semaphores!\n"));
goto errout;
}
/* Create the DR data thread */
m_prefetchThreadID = OS_TaskSpawnParam(
"DR Prefetch Task",
DR_DATATASK_PRIORITY,
DR_PREFETCH_STACK_SIZE,
PrefetchThreadCaller,
this,
NULL
);
if (m_prefetchThreadID == OS_FAILURE)
{
DbgPrint(("\nDRPrefetch: Unable to spawn DRPrefetch Task!\n"));
goto errout;
}
#if DR_TO_DISK
DBGPRINT(DBG_ON(DBG_TRACE), ("\n\n***********************\n"));
DBGPRINT(DBG_ON(DBG_TRACE), ("DR_TO_DISK IS TURNED ON\n"));
DBGPRINT(DBG_ON(DBG_TRACE), ("***********************\n\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -