📄 prmdec.c
字号:
unsigned int WaitCounter = 0;
HX_RESULT retVal = HXR_FAIL;
real_is_V_or_A = 1 ;
switch (ulSubFn)
{
// Return the name of the artist.
case SUBFN_CODEC_GETARTIST:
{
// The second parameter is a pointer for the name.
// Return the name of the artist.
(char *)ulParam2 = (char *)rm_parser_get_author(pParser);
// Success.
return(1);
}
// Return the name of the song
case SUBFN_CODEC_GETTITLE:
{
// Return the name of the song.
(char *)ulParam2 = (char *)rm_parser_get_title(pParser);
// Success.
return(1);
}
// Decode a frame of data.
case SUBFN_CODEC_DECODE:
{
OutLength = (0);
if (NULL == pDepack_a)
return 0;
if (pRawFileCache == NULL)
return 0;
while (OutLength == (0))
{
while_cnt++;
if (while_cnt > 256*4)
{
//Bug Fix: MUST Reset this counter :( by Vincent Hisung
//Jan 13,2008
while_cnt = 0;
//----------------------------
return 0;
}
#if 0
if (isPacketRdy == 1)
{
}
else
{
int i;
//for(i=0;i<4;i++)
while (1)
{
rm_parser_get_packet_a(pParser, &pPacket);
if (pPacket->usStream == usStreamNum_a)
{
isPacketRdy = 1;
break;
//retVal = ra_depack_add_packet(pDepack_a, pPacket);
}
}
}
#endif
//将音频解码拉到这里来做
//------------------------------------------------------
if ((IS_RA_BLOCK_SEND == 1))
{
#if 1
//UINT32 i = 0;
ra_block* pBlock = HXNULL;
ra_depack_internal* pInt = pDepack_a;
/* Get the substream header */
ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[0/*usStreamNum_a*//*bug. To think it out.*/];
/* Send the blocks from the deinterleave buffer */
//for (i = 0; i < pHdr->ulBlockCount && HX_SUCCEEDED(retVal); i++)
if (decode_a_i < pHdr->ulBlockCount)
{
/* Set the return value */
retVal = HXR_OUTOFMEMORY;
/* Compute the time offset for this block */
decode_a_dTimeOffset = decode_a_i * pHdr->dBlockDuration;
decode_a_ulTimeOffset = (UINT32) decode_a_dTimeOffset;
decode_a_ulTimestamp = pHdr->ulKeyTime + decode_a_ulTimeOffset;
/* Make sure the time is less than the stream duration */
//By Vincent Hisung , Jan 06,2008
// Small Bug: For some real file' s TimeLength is 0 or Error,
// Then below judgement always be false...
//if (decode_a_ulTimestamp <= pInt->ulStreamDuration)
if (1)
{
/* Create the ra_block structure */
//pBlock = (ra_block*) ra_depacki_malloc(pInt, sizeof(ra_block));
pBlock = &decode_a_Block;
//------------------------------------
if (pBlock)
{
/* Alloc and copy the buffer */
pBlock->pData = (BYTE*)copy_buffer(pInt->pUserMem,
pInt->fpMalloc,
pHdr->pDBuffer + decode_a_i * pHdr->ulInterleaveBlockSize,
pHdr->ulInterleaveBlockSize);
if (pBlock->pData)
{
pBlock->ulDataLen = pHdr->ulInterleaveBlockSize;
pBlock->ulTimestamp = decode_a_ulTimestamp;
ulCurrentTime = pBlock->ulTimestamp;
pBlock->ulDataFlags = pHdr->pDPresentFlags[decode_a_i];
/* Send the block */
retVal = pInt->fpAvail(pInt->pAvail, usStreamNum_a, pBlock);
}
}
decode_a_i++;
}
else
{
/*
* Block is after the stream duration, so clear
* the return value and break out of the loop.
*/
retVal = HXR_OK;
}
return 1;
//如果要解码 就不在继续解包 因此返回。
}
decode_a_i = 0;
decode_a_ulTimeOffset = 0;
decode_a_ulTimestamp = 0;
decode_a_dTimeOffset = 0.0;
IS_RA_BLOCK_SEND = 0;
/* Clear the interleaving buffers */
if (pHdr->pIBuffer)
memset(pHdr->pIBuffer, 0, pHdr->ulSuperBlockSize);
if (pHdr->pDBuffer)
memset(pHdr->pDBuffer, 0, pHdr->ulSuperBlockSize);
if (pHdr->pIPresentFlags)
memset(pHdr->pIPresentFlags, 0, pHdr->ulInterleaveFactor * sizeof(UINT32));
if (pHdr->pDPresentFlags)
memset(pHdr->pDPresentFlags, 0, pHdr->ulInterleaveFactor * sizeof(UINT32));
/* Clear the state */
pHdr->bHasKeyTime = FALSE;
pHdr->ulKeyTime = 0;
pHdr->ulBlockCount = 0;
#endif
}
//--------------------------
if (IS_RA_BLOCK_SEND2 == 1)
{
if (g_VT_i < g_VT_ulNumAU)
{
//ENTER_CRITICAL();
retVal = do_handle_nonfrag_once(g_VT_i, g_VT_ulNumAU, g_VT_pPacket, pDepack_a, 0/*usStreamNum_a*//*bug. To think it out.*/);
//EXIT_CRITICAL();
ulCurrentTime = g_VT_pPacket->ulTime/*stamp*/;
g_VT_i++;
if (retVal != HXR_OK)
{
IS_RA_BLOCK_SEND2 = 0;
return (0);//error
}
else
{
return(1);
}
}
else
{
IS_RA_BLOCK_SEND2 = 0;
}
}
/* Get the next packet */
#if 0
if (isPacketRdy == 1)
{
retVal = HXR_OK;
isPacketRdy = 0;
ra_depack_add_packet(pDepack_a, pPacket);
}
else
#endif
{
retVal = rm_parser_get_packet_a(pParser, &pPacket);
//EXIT_CRITICAL();
if (retVal == HXR_OK)
{
/* Is this an audio packet? */
if (pPacket->usStream == usStreamNum_a)
{
/*
* Put the packet into the depacketizer. When audio
* blocks are available, we will get a callback
* to ra_block_available()
*/
//ENTER_CRITICAL();
//real_is_V_or_A = 1 ;
retVal = ra_depack_add_packet(pDepack_a, pPacket);
//EXIT_CRITICAL();
}
}
else
{
//已经结束
if (retVal == HXR_AT_END)
{
OutLength = 1152;
return (0);
}
OutLength = 1152;
return (0);
}
}
}
//成功
if (retVal == HXR_OK)
return(1);
//已经结束
if (retVal == HXR_AT_END)
{
OutLength = 0;
return (0);
}
//意外错误
return_decode:
{
return (0); ///ERROR
}
}
// Prepare the codec to decode a file.
case SUBFN_CODEC_OPEN_DEC:
{
//bug fix: don't forget to init these boys :(
//by Vincent Hisung , Nov 27,2007
while_cnt = 0;
IS_RA_BLOCK_SEND = 0 ;
IS_RA_BLOCK_SEND2 = 0 ;
g_VT_ulNumAU = 0;
ra_seek_to_time = 0;
seeked_time = 0;
ra_seekable = 0;
//------------------------------
fp = (MY_FILE*)pRawFileCache;
/* NULL out the info_a */
info_a.fpOut = HXNULL;
info_a.pDepack = HXNULL;
info_a.pDecode = HXNULL;
info_a.pOutBuf = HXNULL;
info_a.ulOutBufSize = 0;
info_a.ulDataBytesWritten = 0;
/* Assign the output file pointer */
info_a.fpOut = (MY_FILE*)0x12345678; //赋值确保.fpOut非空 by Vincent Hisung
/* Read the first few bytes of the file */
lBytesRead = (INT32) RKFIO_FRead((MY_FILE*)fp, (void*) ucBuf, RM2WAV_INITIAL_READ_SIZE);//MOD BY VINCENT
if (lBytesRead != RM2WAV_INITIAL_READ_SIZE)
{
//读取失败
goto cleanup;
}
/* Seek back to the beginning */
RKFIO_FSeek((MY_FILE*)fp, 0, SEEK_SET);
/* Make sure this is an .rm file */
if (!rm_parser_is_rm_file(ucBuf, RM2WAV_INITIAL_READ_SIZE))
{
//非RM文件
goto cleanup;
}
/* Create the parser struct */
pParser = rm_parser_create(NULL, rm2wav_error);
if (!pParser)
{
goto cleanup;
}
/* Set the MY_FILE* into the parser */
retVal = rm_parser_init_stdio(pParser, fp);
if (retVal != HXR_OK)
{
goto cleanup;
}
/* Read all the headers at the beginning of the .rm file */
retVal = rm_parser_read_headers(pParser);
if (retVal != HXR_OK)
{
goto cleanup;
}
/* Get the number of streams */
ulNumStreams = rm_parser_get_num_streams(pParser);
if (ulNumStreams == 0)
{
//获得流数目
goto cleanup;
}
/* Now loop through the stream headers and find the video */
for (i = 0; i < ulNumStreams && retVal == HXR_OK; i++)
{
retVal = rm_parser_get_stream_header(pParser, i, &pHdr_a);
if (retVal == HXR_OK)
{
if (rm_stream_is_realaudio(pHdr_a))
{
usStreamNum_a = (UINT16) i;
//发现音频流[最终确定的视频流为最后发现的视频流]
//从pHdr_a中读取音频相关信息
ulAbr = rm_stream_get_avg_bit_rate(pHdr_a);
//继续判断下一个流
break;
}
else
{
/* Destroy the stream header */
rm_parser_destroy_stream_header(pParser, &pHdr_a);
}
}
}
if (pHdr_a)
{
/* Create the RealAudio depacketizer */
pDepack_a = ra_depack_create((void*) & info_a,
ra_block_available,
NULL,
rm2wav_error);
if (!pDepack_a)
{
goto cleanup;
}
/* Assign the ra_depack pointer to the info_a struct */
info_a.pDepack = pDepack_a;
/* Initialize the RA depacketizer with the stream header */
retVal = ra_depack_init(pDepack_a, pHdr_a);
if (retVal != HXR_OK)
{
goto cleanup;
}
/*
* Get the codec 4CC of substream 0. We
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -