📄 dr_prefetch_bdrom.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_bdrom.cpp
*
* Prefetch class for the DR
*
* $Id: dr_prefetch_bdrom.cpp,v 1.34 2007/01/26 20:49:07 rbehe Exp $
*/
#include <stdlib.h>
#include "vdvd_types.h"
#include "utility.h"
#include "loader_app.h"
#include "dr_types.h"
#include "dr_prefetch_bdrom.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
#define DEBUG_DR_PREFETCH DBG_ERROR
#define DEBUG_PRINTCLIPS DBG_ERROR /*set this lower than DEBUG_DR_PREFETCH to enable adding debug prints with environment variable HDMV_DR_PRINTCLIPS */
#define DEBUG_DEVSEM DBG_VERBOSE /*set this lower than DEBUG_DR_PREFETCH to show debugging information for the device semaphore */
#define DBG_ON(x) (DEBUG_DR_PREFETCH >= x)
#define BD_FILENAMELEN 64
#define BD_TSPACKETSIZE 192
/* maximum jump times (seconds) */
#define BD_TJUMP_ANGLE_MAX (0.350)
#define BD_TJUMP_BSS_MAX (1.010)
/* BDROM Specific Defines */
#define AU_SIZE 6144
/***
* Error Correction I-Frame Jump List
* First error jumps 1 I-frame.
* Second successive jumps 2, then 4, 8, 16, 32
* Then all future successive jumps are by 32
*/
#define JUMPLISTSIZE 6
const BYTE bJumpList[JUMPLISTSIZE] = {1, 2, 4, 8, 16, 32};
#define ERROR_JUMP(jumpindex) ((jumpindex) < (JUMPLISTSIZE)) ? (bJumpList[(jumpindex)]) : (bJumpList[(JUMPLISTSIZE)-1])
/* number of payloads successfully sent by the DR before the jumplist resets back to first index */
#define RESETJUMP 20
/**********************************************
*
* Implementations for DRPrefetch_BDROM Derived Class
*
**********************************************/
/**
* dataRetrieve - retrieve data from the disk and put into the prefetch thread
*
* @param playcmd - contains details for the data retrieval
*
* @retval none
*
* @remarks none.
*/
DR_ERROR DRPrefetch_BDROM::dataRetrieve(PLAYCMD playcmd)
{
DR_ERROR status = DR_SUCCESS;
LOADER_FILE_HANDLE hFileHandle = 0;
BOOLEAN fDataDiscontinuity = FALSE;
BOOLEAN fSendBOS = TRUE;
BOOLEAN fSendEOS = TRUE;
ULONG ulFilenum = playcmd.bdrom.ulFilenum;
BYTE bPlayFlag = playcmd.bdrom.playFlag;
PVOID pvContext = playcmd.bdrom.pvContext;
ULONG tIn = playcmd.bdrom.ulInTime;
ULONG tOut = playcmd.bdrom.ulOutTime;
BYTE ubRefToSTC = playcmd.bdrom.ubRefToSTC;
DR_STREAM strmType = playcmd.bdrom.strmType;
BYTE bAppType;
#ifdef DRM_SUPPORT
ULONG playList_id = playcmd.bdrom.playList_id;
ULONG playItem_id = playcmd.bdrom.playItem_id;
ULONG title_num = playcmd.bdrom.title_num;
#endif
char filename[BD_FILENAMELEN];
ULONGLONG boFirst;
ULONGLONG boLast;
DROUTPUTMESSAGE streamMessage;
/**
* DR's Hungarian Notation Prefixes:
*
* t = time
* bo = byte offset
* ci = coarse index
* fi = fine index
* spn = source packet number
*
**/
snprintf(filename, BD_FILENAMELEN, "/mnt/cdrom/BDMV/STREAM/%.5u.m2ts", ulFilenum);
if ( bPlayFlag != PLAYFLAG_NORMAL )
{
boFirst = (ULONGLONG)playcmd.bdrom.spnIn * BD_TSPACKETSIZE;
boLast = (ULONGLONG)playcmd.bdrom.spnOut * BD_TSPACKETSIZE;
fSendBOS = FALSE;
fSendEOS = (bPlayFlag == PLAYFLAG_SPNEOF);
#ifdef DRM_SUPPORT
playList_id = m_playList_id;
playItem_id = m_playItem_id;
title_num = m_title_num;
#endif
}
else
{
ULONG spnFirst;
ULONG spnLast;
/* check our queue type for discontinuity flag */
if ( (playcmd.bdrom.connectCond == VDVD_CONNECTION_ABORT) || (playcmd.bdrom.connectCond == VDVD_CONNECTION_1) || (playcmd.bdrom.connectCond == VDVD_CONNECTION_NONSEAMLESS_ANGLE) )
{
DBGPRINT(DBG_ON(DBG_TRACE), ("discontinuity at beginning\n"));
fDataDiscontinuity = TRUE;
}
/* get the current clip info and load it into the database */
m_clpInfo.ClpInfoLoad(ulFilenum);
/* put the times and refToSTC into the ClpInfo Database */
m_clpInfo.ClpInfoSet_InOut(ubRefToSTC, tIn, tOut);
/* get the in and out SPN out of the ClpInfo Database */
spnFirst = m_clpInfo.ClpInfoGet_spnFirst();
spnLast = m_clpInfo.ClpInfoGet_spnLast();
/* convert to byte offsets */
boFirst = (ULONGLONG)spnFirst * BD_TSPACKETSIZE;
boLast = (ULONGLONG)spnLast * BD_TSPACKETSIZE;
m_BDspeed.fReverse = playcmd.bdrom.fReverse;
m_BDspeed.bDiscrete = playcmd.bdrom.bDiscrete;
#ifdef DRM_SUPPORT
m_playList_id = playList_id;
m_playItem_id = playItem_id;
m_title_num = title_num;
#endif
}
/* set the current play context */
m_pvPlayContext = pvContext;
bAppType = m_clpInfo.ClpInfoGet_ubAppType();
#ifdef DRM_SUPPORT
if (m_encryption_type == AES_ECB)
{
/*
* TODO: if the content is encrypted get the gey and pass it to the PE
*/
/* drGetKey(playList_id, playItem_id, title_num, boFirst); */
DbgPrint(("%s:%d - NO DRM SUPPORT\n", __FILE__, __LINE__));
}
#endif
#if DBG_ON(DEBUG_PRINTCLIPS)
if ( getenv( "HDMV_DR_PRINTCLIPS" ) )
{
DbgPrint(("\n\n************\n"));
if ( bPlayFlag != PLAYFLAG_NORMAL )
{
DbgPrint(("*SPN Play - dr_id: %u\n", m_idnum));
}
else
{
DbgPrint(("*Normal Play - dr_id: %u\n", m_idnum));
}
DbgPrint(("CLIP: %u\n", ulFilenum));
ULONG ulFileSize;
ULONGLONG ullFileSize;
CLIPINFO_db *pClipInfo = NULL;
m_clpInfo.ClpInfoGet_ClipInfo(&pClipInfo);
m_clpInfo.ClpInfoGet_ClipSize(&ulFileSize);
ullFileSize = (ULONGLONG)ulFileSize * BD_TSPACKETSIZE;
DbgPrint(("length (from clip info): %llu\n", ullFileSize));
LoaderFileSize(m_loader, filename, &ullFileSize);
DbgPrint(("length (from file size): %llu\n\n", ullFileSize));
DbgPrint(("PlayItem:\n"));
DbgPrint(("t/spn in: 0x%x\n", playcmd.bdrom.ulInTime));
DbgPrint(("t/spn out: 0x%x\n", playcmd.bdrom.ulOutTime));
DbgPrint(("boFirst: %llu\n", boFirst));
DbgPrint(("boLast: %llu\n", boLast));
DbgPrint(("output file size: %llu\n\n", boLast-boFirst));
DbgPrint(("connection condition: %u\n", playcmd.bdrom.connectCond));
DbgPrint(("application type: %u\n", bAppType));
DbgPrint(("TS_recording_rate: %u\n\n", pClipInfo->TS_recording_rate));
if (boLast > ullFileSize)
{
DbgPrint(("\n\nERROR! WILL ATTEMPT TO PLAY PAST THE END!!\n\n"));
}
}
#endif
OS_SemGive(m_semPlayQueueEnabled);
/* Sanity Checks */
if (boFirst > boLast)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PrefetchThread(): dataRetrieve -- error on disk - boFirst larger than boLast\n"));
status = FAILURE;
goto out;
}
if (m_fAbort == TRUE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PrefetchThread(): dataRetrieve -- Aborted Play\n"));
status = FAILURE;
goto out;
}
/* Ready to go - send the Beginning of Stream (if required) */
if(fSendBOS == TRUE)
{
streamMessage.BegOfStream = TRUE;
streamMessage.StreamContext = pvContext;
drSendStream(streamMessage, NULL);
}
/* if it's a subtitle stream, first send the font list */
if (strmType == DR_STREAM_BDROM_SUBPATH_TEXT_SUBTITLE)
{
UBYTE numFiles;
UBYTE *font_names;
m_clpInfo.ClpInfoGet_FontInfo(&numFiles, &font_names);
drSendSubtextInfo(numFiles, font_names, tIn, pvContext);
}
if (bAppType == 2)
{
tIn = m_clpInfo.ClpInfoGet_ptsFirst();
}
/* for all stream types, send a timingInfo payload */
if ( (fSendBOS == TRUE) && (playcmd.bdrom.connectCond != VDVD_CONNECTION_SEAMLESS_ANGLE) )
{
drSendTimingInfo(bAppType, playcmd.bdrom.connectCond, tIn, tOut, pvContext);
}
if (m_fAbort == TRUE)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PrefetchThread(): dataRetrieve -- Aborted Play\n"));
status = FAILURE;
goto out;
}
/* open the file from which we want to stream */
if (LOADER_SUCCESS != LoaderFileOpenAV(m_loader, filename, &hFileHandle) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("dataRetrieve() -- Error Opening File\n"));
hFileHandle = 0;
status = FAILURE;
goto out;
}
/* discrete trickmode, timebased slideshow, or reverse playback */
if( ( (bAppType == 2) || m_BDspeed.bDiscrete || m_BDspeed.fReverse) && m_clpInfo.ClpInfoIsEPMapped() && (bPlayFlag == PLAYFLAG_NORMAL) )
{
COARSEINFO *pClpInfoEpMapCoarse = NULL;
ULONG ulNumCoarseEntries = 0;
FINEINFO *pClpInfoEpMapFine = NULL;
ULONG ulNumFineEntries = 0;
//const ULONG I_tp_size[8] = {0, 131072, 262144, 393216, 589824, 917504, 1310720, 0}; /* real values */
const ULONG I_tp_size[8] = {0, 131136, 262272, 393216, 589824, 917568, 1310784, 0}; /* rounded up to a full source packet (x%192=0) */
ULONG ciTrickLow;
ULONG ciTrickHigh;
ULONG fiTrickLow;
ULONG fiTrickHigh;
ULONG ciTrickStart;
ULONG ciTrickEnd;
ULONG fiTrickStart;
ULONG fiTrickEnd;
SHORT increment;
ULONG spnCurr;
ULONG spnNext;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -