📄 clpinfodb.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 clpinfodb.cpp
*
* API to the Clip Info Database.
* The Clip Info Database handles the storage of and access to Clip Info data.
*
* $Id: clpinfodb.cpp,v 1.7 2007/01/26 20:39:19 rbehe Exp $
*/
#include <string.h>
#include "vdvd_types.h"
#include "clpinfodb.h"
#include "loader_app.h"
#include "osapi.h"
#include "utility.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* Debug macros */
#define DBG_CLPINFO DBG_ERROR
#define DBG_PRINTEP DBG_VERBOSE
#define DBG_ON(x) (DBG_CLPINFO >= x)
#define CLPINFO_DATA_BUFFER_SZ (2621440) // (2.5MB) Max size of all clipinfo files for one playlist is 2MB,
// but allocate extra 1/2 MB for overhead.
#define CLPINFO_MAX_ENTRIES (999 + 255) // Annex B of BD spec
/**
* Clip Info Entry.
*/
typedef struct tagCLPINFO_ENTRY
{
ULONG ulClipnum;
CLPINFO_DATABASE tClpInfoData;
} CLPINFO_ENTRY;
/**
* Clip Info Module data.
*/
typedef struct tagCLPINFO_HANDLE
{
CLPINFO_ENTRY *ClpInfo_Entry[CLPINFO_MAX_ENTRIES];
ULONG ulNumClipsLoaded;
UBYTE *LoadBuffer;
ULONG ulDataPosition;
LOADER_HANDLE hLoader;
} CLPINFO_HANDLE;
/* Clip Info Module Handle */
CLPINFO_HANDLE *hClpInfo = NULL;
/**
* Local Functions
*/
static CLPINFO_STATUS clpinfoLoadMainData(CLPINFO_ENTRY *clipinfo_entry, LOADER_FILE_HANDLE ClpInfoFile, ULONG offset);
static CLPINFO_STATUS clpinfoLoadClipInfo(CLPINFO_ENTRY *clipinfo_entry, LOADER_FILE_HANDLE ClpInfoFile, ULONG offset);
static CLPINFO_STATUS clpinfoLoadSequenceInfo(CLPINFO_ENTRY *clipinfo_entry, LOADER_FILE_HANDLE ClpInfoFile, ULONG offset);
static CLPINFO_STATUS clpinfoLoadProgramInfo(CLPINFO_ENTRY *clipinfo_entry, LOADER_FILE_HANDLE ClpInfoFile, ULONG offset);
static CLPINFO_STATUS clpinfoLoadStreamCodingInfo(LOADER_FILE_HANDLE ClpInfoFile, STREAMCODINGINFO *StreamCodingInfo);
static CLPINFO_STATUS clpinfoLoadCPI(CLPINFO_ENTRY *clipinfo_entry, LOADER_FILE_HANDLE ClpInfoFile, ULONG offset);
static PVOID clpinfoGetBuffer(ULONG ulSize);
/**
* ClpInfoMgrCreate -- Create the Clip Info database
*
* @param
* tLoader -- handle to the loader.
*
* @retval
* CLPINFO_STATUS
*/
CLPINFO_STATUS ClpInfoMgrCreate(LOADER_HANDLE tLoader)
{
/* validate parameter */
if (tLoader == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrCreate: Null pointer!\n"));
return (CLPINFO_NULL_PTR);
}
/* If database is already created, return a failure */
if (hClpInfo != NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrCreate: Database already created!\n"));
return (CLPINFO_FAILURE);
}
/* Create Clip Info Module handle */
hClpInfo = (CLPINFO_HANDLE *)OS_MemAlloc(sizeof(CLPINFO_HANDLE));
if (hClpInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrCreate: Failed to create clip info module handle!\n"));
goto errout;
}
/* Init Clip Info Module handle */
memset(hClpInfo, 0, sizeof(CLPINFO_HANDLE));
/* Create the buffer that will hold the loaded clip info */
hClpInfo->LoadBuffer = (UBYTE *)OS_MemAlloc(CLPINFO_DATA_BUFFER_SZ);
if (hClpInfo->LoadBuffer == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrCreate: Failed to create buffer!\n"));
goto errout;
}
/* Keep loader handle */
hClpInfo->hLoader = tLoader;
return (CLPINFO_SUCCESS);
errout:
ClpInfoMgrDelete();
return (CLPINFO_FAILURE);
}
/**
* ClpInfoMgrDelete -- Delete the clip info database
*
* @param
* none
*
* @retval
* CLPINFO_STATUS
*/
CLPINFO_STATUS ClpInfoMgrDelete(void)
{
CLPINFO_STATUS tStatus = CLPINFO_SUCCESS;
/* If database has not been created, return a failure */
if (hClpInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrDelete: Database doesn't exist!\n"));
tStatus = CLPINFO_FAILURE;
}
else
{
/* unload any loaded clip info */
ClpInfoMgrUnload();
/* delete buffer */
if (hClpInfo->LoadBuffer != NULL)
{
OS_MemFree(hClpInfo->LoadBuffer);
hClpInfo->LoadBuffer = NULL;
}
/* delete handle */
OS_MemFree(hClpInfo);
hClpInfo = NULL;
}
return (tStatus);
}
/**
* ClpInfoMgrLoad -- Load the Clip Info data from BDROM disc into the database.
*
* @param
* none
*
* @retval
* CLPINFO_STATUS
*/
CLPINFO_STATUS ClpInfoMgrLoad(ULONG ulClipnum)
{
LOADER_FILE_HANDLE ClpInfoFile = 0;
LOADER_FILE_HANDLE ClpInfoBkupFile = 0;
CLPINFO_STATUS tStatus = CLPINFO_SUCCESS;
char filename[64];
char bkup_filename[64];
ULONG ulClipInfoIndex;
ULONG i;
BOOLEAN fBackupLoaded = FALSE;
if (hClpInfo == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoad: Database not created!\n"));
return (CLPINFO_FAILURE);
}
/* check if there are too many clips loaded */
if (hClpInfo->ulNumClipsLoaded >= CLPINFO_MAX_ENTRIES)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoad: Maximum number of entries already loaded!\n"));
return (CLPINFO_FAILURE);
}
/* Check if this clip info is already loaded */
for (i = 0; i < hClpInfo->ulNumClipsLoaded; i++)
{
if ( (hClpInfo->ClpInfo_Entry[i] != NULL) && (ulClipnum == hClpInfo->ClpInfo_Entry[i]->ulClipnum) )
{
DBGPRINT(DBG_ON(DBG_VERBOSE), ("ClpInfoMgrLoad: This clip is already loaded! (no need to reload)\n"));
return (CLPINFO_SUCCESS);
}
}
/* Set new clip entry info index */
ulClipInfoIndex = hClpInfo->ulNumClipsLoaded;
/* Create a new clip info entry, using our static buffer */
hClpInfo->ClpInfo_Entry[ulClipInfoIndex] = (CLPINFO_ENTRY *)clpinfoGetBuffer(sizeof(CLPINFO_ENTRY));
if (hClpInfo->ClpInfo_Entry[ulClipInfoIndex] == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoad: Failed to create clip info entry!\n"));
return (CLPINFO_FAILURE);
}
/* Initialize clip info entry data */
memset(hClpInfo->ClpInfo_Entry[ulClipInfoIndex], 0, sizeof(CLPINFO_ENTRY));
/* Set clip number of this clip entry */
hClpInfo->ClpInfo_Entry[ulClipInfoIndex]->ulClipnum = ulClipnum;
/* Open the Clip Info file */
snprintf(filename, 64, "/mnt/cdrom/BDMV/CLIPINF/%.5u.clpi", ulClipnum);
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Open ClpInfoFile: %s\n", filename));
if (LoaderFileOpen(hClpInfo->hLoader, filename, &ClpInfoFile) != LOADER_SUCCESS)
{
ClpInfoFile = 0;
}
/* Make sure at least one file opened successfully. */
if (ClpInfoFile == 0)
{
fBackupLoaded = TRUE;
/* Open the Clip Info BACKUP file */
snprintf(bkup_filename, 64, "/mnt/cdrom/BDMV/BACKUP/CLIPINF/%.5u.clpi", ulClipnum);
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Open ClpInfoBkupFile: %s\n", bkup_filename));
if (LoaderFileOpen(hClpInfo->hLoader, bkup_filename, &ClpInfoBkupFile) != LOADER_SUCCESS)
{
ClpInfoBkupFile = 0;
}
if (ClpInfoBkupFile == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoad: Could not open ClipInfo file!\n"));
tStatus = CLPINFO_FILE_ERROR;
goto errout;
}
else
{
/* use backup file */
ClpInfoFile = ClpInfoBkupFile;
ClpInfoBkupFile = 0;
}
}
/*
* Now, load the clip info from the file off the disc. All data will
* be loaded into our static buffer. All allocations should use clpinfoGetBuffer(),
* which allocates memory from our static buffer.
*/
/* Read the Clip Info Main Data */
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Read Clip Info Main Data\n"));
if (CLPINFO_SUCCESS != clpinfoLoadMainData(hClpInfo->ClpInfo_Entry[ulClipInfoIndex], ClpInfoFile, 0))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoadMainData Failed!\n"));
if (fBackupLoaded == FALSE)
{
fBackupLoaded = TRUE;
/* Open the Clip Info BACKUP file */
snprintf(bkup_filename, 64, "/mnt/cdrom/BDMV/BACKUP/CLIPINF/%.5u.clpi", ulClipnum);
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Open ClpInfoBkupFile: %s\n", bkup_filename));
if (LoaderFileOpen(hClpInfo->hLoader, bkup_filename, &ClpInfoBkupFile) != LOADER_SUCCESS)
{
ClpInfoBkupFile = 0;
}
}
if (ClpInfoBkupFile == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoad: No BACKUP!\n"));
tStatus = CLPINFO_FILE_ERROR;
goto errout;
}
if (CLPINFO_SUCCESS != clpinfoLoadMainData(hClpInfo->ClpInfo_Entry[ulClipInfoIndex], ClpInfoBkupFile, 0))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoadMainData BACKUP Failed!\n"));
tStatus = CLPINFO_FILE_ERROR;
goto errout;
}
}
/* Read the Clip Info ClipInfo() Table */
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Read Clip Info ClipInfo()\n"));
if (CLPINFO_SUCCESS != clpinfoLoadClipInfo(hClpInfo->ClpInfo_Entry[ulClipInfoIndex], ClpInfoFile, 40))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoadClipInfo Failed!\n"));
if (fBackupLoaded == FALSE)
{
fBackupLoaded = TRUE;
/* Open the Clip Info BACKUP file */
snprintf(bkup_filename, 64, "/mnt/cdrom/BDMV/BACKUP/CLIPINF/%.5u.clpi", ulClipnum);
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Open ClpInfoBkupFile: %s\n", bkup_filename));
if (LoaderFileOpen(hClpInfo->hLoader, bkup_filename, &ClpInfoBkupFile) != LOADER_SUCCESS)
{
ClpInfoBkupFile = 0;
}
}
if (ClpInfoBkupFile == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoad: No BACKUP!\n"));
tStatus = CLPINFO_FILE_ERROR;
goto errout;
}
if (CLPINFO_SUCCESS != clpinfoLoadClipInfo(hClpInfo->ClpInfo_Entry[ulClipInfoIndex], ClpInfoBkupFile, 128))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoadClipInfo BACKUP Failed!\n"));
tStatus = CLPINFO_FILE_ERROR;
goto errout;
}
}
/* Read the Clip Info SequenceInfo() Table */
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Read Clip Info SequenceInfo()\n"));
if (CLPINFO_SUCCESS != clpinfoLoadSequenceInfo(hClpInfo->ClpInfo_Entry[ulClipInfoIndex], ClpInfoFile, hClpInfo->ClpInfo_Entry[ulClipInfoIndex]->tClpInfoData.SequenceInfo_start_address))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoadSequenceInfo Failed!\n"));
if (fBackupLoaded == FALSE)
{
fBackupLoaded = TRUE;
/* Open the Clip Info BACKUP file */
snprintf(bkup_filename, 64, "/mnt/cdrom/BDMV/BACKUP/CLIPINF/%.5u.clpi", ulClipnum);
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Open ClpInfoBkupFile: %s\n", bkup_filename));
if (LoaderFileOpen(hClpInfo->hLoader, bkup_filename, &ClpInfoBkupFile) != LOADER_SUCCESS)
{
ClpInfoBkupFile = 0;
}
}
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoadClipInfo Failed!\n"));
if (ClpInfoBkupFile == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoad: No BACKUP!\n"));
tStatus = CLPINFO_FILE_ERROR;
goto errout;
}
if (CLPINFO_SUCCESS != clpinfoLoadSequenceInfo(hClpInfo->ClpInfo_Entry[ulClipInfoIndex], ClpInfoBkupFile, hClpInfo->ClpInfo_Entry[ulClipInfoIndex]->tClpInfoData.SequenceInfo_start_address))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ClpInfoMgrLoadSequenceInfo BACKUP Failed!\n"));
tStatus = CLPINFO_FILE_ERROR;
goto errout;
}
}
/* Read the Clip Info ProgramInfo() Table */
DBGPRINT(DBG_ON(DBG_TRACE), ("ClpInfoMgrLoad: Read Clip Info ProgramInfo()\n"));
if (CLPINFO_SUCCESS != clpinfoLoadProgramInfo(hClpInfo->ClpInfo_Entry[ulClipInfoIndex], ClpInfoFile, hClpInfo->ClpInfo_Entry[ulClipInfoIndex]->tClpInfoData.ProgramInfo_start_address))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -