📄 prmdec_v.c
字号:
/* 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_v);
if (retVal == HXR_OK)
{
if (rm_stream_is_realvideo(pHdr_v))
{
//发现视频流[最终确定的视频流为最后发现的视频流]
usStreamNum_v = (UINT16) i;
//继续判断下一个流
//pHdr_v=0;
//屏蔽视频流
break;
}
else
{
/* Destroy the stream header */
rm_parser_destroy_stream_header(pParser, &pHdr_v);
}
}
}
/* Do we have a RealVideo stream in this .rm file? */
//如果存在视频流
if (pHdr_v)
{
/* Create the RealVideo depacketizer */
pDepack_v = rv_depack_create((void*) & info_v,
rv_frame_available,
NULL,
rm2yuv_error);
if (!pDepack_v)
{
goto cleanup;
}
/* Assign the rv_depack pointer to the info_v struct */
info_v.pDepack = pDepack_v;
/* Initialize the RV depacketizer with the stream header */
retVal = rv_depack_init(pDepack_v, pHdr_v);
if (retVal != HXR_OK)
{
goto cleanup;
}
/* Get the bitstream header information */
retVal = rv_depack_get_codec_init_info(pDepack_v, &pInfo_v);
if (retVal != HXR_OK)
{
goto cleanup;
}
{
BYTE *pTmp = (BYTE*) malloc(pInfo_v->ulLength);
PackRVFormatInfo(pInfo_v, pTmp, pInfo_v->ulLength);
memcpy(RV_SliceDataBuf, pTmp, pInfo_v->ulLength);
cur_RV_SliceDataLen = pInfo_v->ulLength;
free(pTmp);
}
/* Fill in the width and height */
info_v.ulWidth = (UINT32) pInfo_v->usWidth;
info_v.ulHeight = (UINT32) pInfo_v->usHeight;
/*
* Get the frames per second. This value is in 32-bit
* fixed point, where the upper 16 bits is the integer
* part of the fps, and the lower 16 bits is the fractional
* part. We're going to truncate to integer, so all
* we need is the upper 16 bits.
*/
ulFramesPerSec = pInfo_v->ufFramesPerSecond >> 16;
/* Create an rv_decode object */
pDecode_v = rv_decode_create(HXNULL, rm2yuv_error);
if (!pDecode_v)
{
goto cleanup;
}
/* Assign the decode object into the rm2yuv_info struct */
info_v.pDecode = pDecode_v;
/* Init the rv_decode object */
retVal = rv_decode_init(pDecode_v, pInfo_v);
if (retVal != HXR_OK)
{
goto cleanup;
}
//We only Support RV9,10 now :(
//add by Vincent Hisung ,Nov 28,2007
CurrentRealVideoVersion = pDecode_v->ulMajorBitstreamVersion;
/*if(pDecode_v->ulMajorBitstreamVersion != RAW_RV9_MAJOR_VERSION)
{
//if(pDecode_v->ulMajorBitstreamVersion != RAW_RV8_MAJOR_VERSION) ....
//goto cleanup;
}*/
/* get the max size of packet */
{
unsigned long ulMaxPacket = rm_parser_get_max_packet_size(pParser);
p_decode_a_new_packetData_v = malloc(ulMaxPacket);
maxPacketSize = ulMaxPacket;
pFrameData = malloc(ulMaxPacket);
}
//Vincent Hisung : Test for speed up SEEK
if (HXR_OK == rm_parser_seek(pParser, rm_parser_get_duration(pParser)))
{
rv_seekable = 1;
}
else
{
rv_seekable = 0;
}
rm_parser_seek(pParser, 0);
TotalTimeLength = rm_parser_get_duration(pParser);
//If we can't get duration from parser,use the duration of stream instead.
//NOTE: may cause some other problem.
// By Vincent Hsiung, Mar 12th, 2008
if (TotalTimeLength == 0)
TotalTimeLength = rm_stream_get_duration(pHdr_v);
//----------------------------------------------------------------------------------------------------------------
rm_parser_seek(pParser, 0);
{
rm_parser_internal* ptmp = (rm_parser_internal*)pParser;
rm_parseri_file_seek(ptmp, ptmp->propHdr.data_offset +
18, 0);
}
}
else
{
//Bug Fix: Dec 11,2007,Vincent Hisung
goto cleanup;
}
//------------------------------------------------------
return(1);//return success message.
cleanup:
if (p_decode_a_new_packetData_v)
{
free(p_decode_a_new_packetData_v);
p_decode_a_new_packetData_v = NULL;
}
if (pFrameData)
{
free(pFrameData);
pFrameData = NULL;
}
if (pDecode_v)
{
rv_decode_destroy(&pDecode_v);
}
/* Destroy the codec init info_v */
if (pInfo_v)
{
rv_depack_destroy_codec_init_info(pDepack_v, &pInfo_v);
}
/* Destroy the depacketizer */
if (pDepack_v)
{
rv_depack_destroy(&pDepack_v);
}
/* If we have a packet, destroy it */
if (pPacket)
{
rm_parser_destroy_packet(pParser, &pPacket);
}
if (pHdr_v)
{
rm_parser_destroy_stream_header(pParser, &pHdr_v);
}
/* Destroy the parser */
if (pParser)
{
rm_parser_destroy(&pParser);
}
return (0);//return error
}
unsigned long Real_GetVideoVersion(void)
{
return CurrentRealVideoVersion;
}
void RVDeInit(void)
{
if (p_decode_a_new_packetData_v)
{
free(p_decode_a_new_packetData_v);
p_decode_a_new_packetData_v = NULL;
}
if (pFrameData)
{
free(pFrameData);
pFrameData = NULL;
}
if (pDecode_v)
{
rv_decode_destroy(pDecode_v);
}
/* Destroy the codec init info_v */
if (pInfo_v)
{
rv_depack_destroy_codec_init_info(pDepack_v, &pInfo_v);
}
/* Destroy the depacketizer */
if (pDepack_v)
{
rv_depack_destroy(&pDepack_v);
}
/* If we have a packet, destroy it */
/* if (pPacket)
{
rm_parser_destroy_packet(pParser, &pPacket);
}*/
if (pHdr_v)
{
rm_parser_destroy_stream_header(pParser, &pHdr_v);
}
/* Destroy the parser */
if (pParser)
{
rm_parser_destroy(&pParser);
}
}
extern unsigned short AudioPlayState;
#include "RealFun.h"
extern void SyncEnableFunc(unsigned long tm);
long RV_GetNextFrameTime(unsigned long Time)
{
return rm_get_next_pos_after_sp_time(pParser, Time, usStreamNum_v);
}
int RVFillBuf()
{
unsigned int NumCout = 0; //用于记录搜索的次数
numOfRVOut = 0;
while (numOfRVOut == 0)
{
if (Real_DecodeState != REAL_DECODE_STATE_PLAYING)
{
if ((Real_DecodeState == REAL_DECODE_STATE_FFDSEEK) && isCanBeSeek)
{
Real_CurrentSeekingTime += REAL_SEEKING_TIMEDISTANCE;
if (HXR_OK != rm_parser_seek_sp(pParser, Real_CurrentSeekingTime, usStreamNum_v)) //遇到搜索失败,退出
return 0;
}
else if ((Real_DecodeState == REAL_DECODE_STATE_FFWSEEK) && isCanBeSeek)
{
if (Real_CurrentSeekingTime >= REAL_SEEKING_TIMEDISTANCE)
Real_CurrentSeekingTime -= REAL_SEEKING_TIMEDISTANCE;
else
Real_CurrentSeekingTime = 0;
if (HXR_OK != rm_parser_seek_sp(pParser, Real_CurrentSeekingTime, usStreamNum_v))
return 0;
}
else if (Real_DecodeState == REAL_DECODE_STATE_FFDEND)
{
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoStartAudio, (void*)(ulCurrentTime + 1500));
Real_DecodeState = REAL_DECODE_STATE_PLAYING;
RV_SeekEnd_AudioEN = 1;
if (RealAudioExist)
RV_SkipFrameEn = 0;
SyncEnableFunc(ulCurrentTime);
}
else if (Real_DecodeState == REAL_DECODE_STATE_FFWEND)
{
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoStartAudio, (void*)(ulCurrentTime + 1500));
Real_DecodeState = REAL_DECODE_STATE_PLAYING;
RV_SeekEnd_AudioEN = 1;
if (RealAudioExist)
RV_SkipFrameEn = 0;
SyncEnableFunc(ulCurrentTime);
}
else if (Real_DecodeState == REAL_DECODE_STATE_POSSEEKSTART && isCanBeSeek)
{
Real_DecodeState = REAL_DECODE_STATE_POSSEEKEND;
Real_CurrentSeekingTime = PosSeekVal;
if (HXR_OK != rm_parser_seek_sp(pParser, Real_CurrentSeekingTime, usStreamNum_v))
return 0;
}
else if (Real_DecodeState == REAL_DECODE_STATE_POSSEEKEND && isCanBeSeek)
{
if (RV_SeekEnd_AudioEN)
RockOSSendMsg(MBVIDEO, AS_GUVI_VideoStartAudio, (void*)(ulCurrentTime + 500));
Real_DecodeState = REAL_DECODE_STATE_PLAYING;
SyncEnableFunc(ulCurrentTime);
}
}
real_is_V_or_A = 0;
/* Get the next packet */
//retVal = rm_parser_get_packet(pParser, &pPacket);
retVal = rm_parser_get_packet_v(pParser, &pPacket);
if (retVal == HXR_OK)
{
/* Is this a video packet? */
if (pPacket->usStream == usStreamNum_v)
{
/*
* Put the packet into the depacketizer. When frames
* are available, we will get a callback to
* rv_frame_available().
*/
real_is_V_or_A = 0;
//retVal = rv_depack_add_packet(pDepack_v, pPacket);
retVal = rv_depack_add_packet(pDepack_v, pPacket);
return 1;
}
else
{
if ((++NumCout >= 8) && (Real_CurrentSeekingTime >= TotalTimeLength)) //最后的关键帧搜索不到时强制退出
return 0;
}
}
else
{
//已经结束
if (retVal == HXR_AT_END)
{
return (0);
}
//其它错误
return (0); ///////return 1 for debug
}
}
//意外错误
return_decode:
{
return (0); ///ERROR
}
}
int GetIsRVSeekable()
{
return rv_seekable;
}
UINT32 RVGetTotalTimeLength(void)
{
return TotalTimeLength;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -