?? ccparse.c
字號:
#include <string.h> #include "rmlibcw/include/rmlibcw.h"#define DEBUG DISABLE#define INFO DISABLE#define WARNING ENABLE#define ERROR ENABLE#include "ccparse.h"struct bcc_header{ RMuint32 signature; RMuint32 frameoffset; RMuint32 reserved1; RMuint32 reserved2;};struct bcc_index_entry{ RMuint32 ptsMilliseconds; RMuint32 fileOffset;};struct rmbcc{ RMfile file; RMbool is_open; struct bcc_index_entry current_index; struct bcc_index_entry next_index; RMint64 next_index_offset; RMint64 next_data_offset;};/* Bcc file identification signature. Always 0x0bccbcc0 */#define BCC_SIGNATURE_VALUE 0x0bccbcc0/* Time offset of start of movie versus video start. Never has been non-0. (but * could be) */#define BCC_FRAMEOFFSET_VALUE 0/* Reserved. Set to 0. */#define BCC_RESERVED_VALUE 0/* The end of the index section is identified by a time stamp of 0xffffffff */#define BCC_END_OF_INDEX_SECTION 0xffffffff/* prototypes */static RMstatus rmbcc_get_next_index_entry(rmbcc_t *);/* implementation */rmbcc_t *rmbcc_create(void){ static const rmbcc_t init = { 0 }; rmbcc_t *bcc; bcc = RMMalloc(sizeof *bcc); if (NULL != bcc) { memcpy(bcc, &init, sizeof init); } return bcc;}RMstatus rmbcc_destroy(rmbcc_t *bcc){ RMstatus status = RM_OK; if (rmbcc_is_open(bcc)) { status = rmbcc_close(bcc); } RMFree(bcc); return status;}RMbool rmbcc_is_open(rmbcc_t *bcc){ return bcc -> is_open;}RMstatus rmbcc_open(rmbcc_t *bcc, RMnonAscii *file_name){ RMstatus status = RM_OK; bcc -> file = RMOpenFile(file_name, RM_FILE_OPEN_READ); if (NULL == bcc -> file) { status = RM_ERROR; } else { struct bcc_header header; RMuint32 header_size = sizeof header; RMuint32 size_read = 0; RMuint8 buffer[header_size]; status = RMReadFile(bcc -> file, buffer, header_size, &size_read); if (RM_OK == status) { RMuint8 *buffer_ptr = buffer; header.signature = RMbeBufToUint32(buffer_ptr); buffer_ptr += sizeof header.signature; header.frameoffset = RMbeBufToUint32(buffer_ptr); buffer_ptr += sizeof header.frameoffset; header.reserved1 = RMbeBufToUint32(buffer_ptr); buffer_ptr += sizeof header.reserved1; header.reserved2 = RMbeBufToUint32(buffer_ptr); RMDBGLOG((INFO, "Header read succeeded\n")); if (BCC_SIGNATURE_VALUE != header.signature) { RMDBGLOG(( ERROR, "Invalid signature %#8x: file is not a BCC file\n", header.signature)); rmbcc_close(bcc); status = RM_ERROR; } else { if (BCC_FRAMEOFFSET_VALUE != header.frameoffset || BCC_RESERVED_VALUE != header.reserved1 || BCC_RESERVED_VALUE != header.reserved2) { RMDBGLOG(( WARNING, "Abnormal values detected in BCC file header:\n" " Signature: %#8x (should be 0x0bccbcc0)\n" " Frame offset: %#8x (should be 0)\n" " Reserved1: %#8x (should be 0)\n" " Reserved2: %#8x (should be 0)\n", header.signature, header.frameoffset, header.reserved1, header.reserved2)); } bcc -> is_open = TRUE; RMGetCurrentPositionOfFile(bcc -> file, &bcc -> next_index_offset); rmbcc_get_next_index_entry(bcc); bcc -> next_data_offset = bcc -> next_index.fileOffset; RMSeekFile(bcc -> file, bcc -> next_data_offset, RM_FILE_SEEK_START); } } } return status;}RMstatus rmbcc_close(rmbcc_t *bcc){ RMstatus status = RMCloseFile(bcc -> file); if (RM_OK == status) { bcc -> file = NULL; bcc -> is_open = FALSE; } return status;}RMstatus rmbcc_get_next_entry(rmbcc_t *bcc, struct CCFifo_CCEntry_type *pentry){ RMstatus status = RM_ERROR; if (rmbcc_is_open(bcc) && NULL != pentry) { /* first, see if we need to read another index entry */ if (bcc -> next_data_offset >= bcc -> next_index.fileOffset) { rmbcc_get_next_index_entry(bcc); if (BCC_END_OF_INDEX_SECTION == bcc -> next_index.ptsMilliseconds) { status = RM_ERRORENDOFFILE; } } if (RM_ERRORENDOFFILE != status) { /* read data */ RMuint8 buffer[2]; RMuint32 size_read = 0; status = RMReadFile(bcc -> file, buffer, sizeof buffer, &size_read); if (RM_OK == status) { bcc -> next_data_offset += sizeof buffer; RMDBGLOG((DEBUG, "bcc -> next_data_offset = %#8x\n", bcc -> next_data_offset)); /* we have gathered all we need. create the cc entry */ pentry -> Enable = TRUE; pentry -> PtsEnable = TRUE; pentry -> Type = EMhwlibCCType_TopField; pentry -> Pts = bcc -> current_index.ptsMilliseconds; pentry -> CC1 = buffer[0]; pentry -> CC2 = buffer[1];#ifdef _DEBUG { RMascii cc[3] = { 0 }; cc[0] = pentry -> CC1 & 0x7f; cc[1] = pentry -> CC2 & 0x7f; cc[2] = 0; RMDBGLOG(( INFO, "CC entry created successfully:\n" "Enable = %s\n" "PtsEnable = %s\n" "Type = %s\n" "Pts = %llu\n" "CC1 = %#2x\n" "CC2 = %#2x\n" "CC = %s\n", pentry -> Enable ? "true" : "false", pentry -> PtsEnable ? "true" : "false", pentry -> Type == EMhwlibCCType_TopField ? "EMhwlibCCType_TopField" : "EMhwlibCCType_BottomField", pentry -> Pts, pentry -> CC1, pentry -> CC2, ((pentry -> CC1 & 0xf0) == 0x10) ? "\\n" : cc)); }#endif } } } return status;}static RMstatus rmbcc_get_next_index_entry(rmbcc_t *bcc){ RMstatus status = RM_ERROR; if (rmbcc_is_open(bcc)) { /* read next index entry */ struct bcc_index_entry index_entry; RMuint32 index_entry_size = sizeof index_entry; RMuint32 size_read = 0; RMuint8 buffer[index_entry_size]; /* position the file pointer at the next index entry */ RMSeekFile(bcc -> file, bcc -> next_index_offset, RM_FILE_SEEK_START); status = RMReadFile(bcc -> file, buffer, index_entry_size, &size_read); if (RM_OK == status) { RMuint8 *buffer_ptr = buffer; bcc -> next_index_offset += index_entry_size; RMDBGLOG((DEBUG, "bcc -> next_index_offset = %#8x\n", bcc -> next_index_offset)); /* move the "next index entry" to the "current index entry" */ memcpy(&bcc -> current_index, &bcc -> next_index, sizeof bcc -> next_index); /* sanity check */ RMASSERT((bcc -> next_data_offset == bcc -> current_index.fileOffset)); /* and fill the "next index entry" with the values just read */ bcc -> next_index.ptsMilliseconds = RMbeBufToUint32(buffer_ptr);#ifdef WITH_BCC_CC_FRAME_TO_MS_PTS_HACK /* ***HACK*** transform frame # into milliseconds */ bcc -> next_index.ptsMilliseconds *= 1001; bcc -> next_index.ptsMilliseconds /= 30;#endif /* WITH_BCC_CC_FRAME_TO_MS_PTS_HACK */ buffer_ptr += sizeof bcc -> next_index.ptsMilliseconds; bcc -> next_index.fileOffset = RMbeBufToUint32(buffer_ptr); RMDBGLOG((INFO, "Index read succeeded\n")); RMDBGLOG(( DEBUG, "PTS = %lu\n" "Offset = %#8x\n", bcc -> next_index.ptsMilliseconds, bcc -> next_index.fileOffset)); /* re-position the file pointer at the next data entry */ RMSeekFile(bcc -> file, bcc -> next_data_offset, RM_FILE_SEEK_START); } } return status;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -