📄 prmdec_v.c
字号:
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*
File : \Audio\RMDec
Desc : RM音频解码【LBR,AAC】,RV视频解包。
Author : Vincent Hisung
Date : 2007-08-xx
Notes : 部分功能未经测试
$Log :
*
* vincent 2007/08/xx 建立此文件
*
*/
/****************************************************************/
#define ARM_ADS
#include <stdlib.h>
#include <time.h>
#include "pRmDec.h"
#include "include.h"
#include "../include/audio_globals.h"
#include "../include/CommonCmd.h"
#define RM2YUV_INITIAL_READ_SIZE 16
#include "../include/file_access.h"
#define RV_SLICEDATABUF_SIZE 4096*8
unsigned long maxPacketSize = 0;
static char RV_SliceDataBuf[RV_SLICEDATABUF_SIZE];
static long volatile cur_RV_SliceDataLen = 0;
static unsigned long seek_time = -1;
unsigned long seeked_time = -1;
static int rv_seekable = 0;
extern UINT32 rm_get_next_pos_after_sp_time(rm_parser_internal*, UINT32 ulSeekTime, UINT32 ulStream);
extern int real_is_V_or_A; // 0 - V . 1 - A
extern char* p_decode_a_new_packetData_v ;
extern void* pFrameData ;
extern unsigned long PosSeekVal;
typedef struct
{
MY_FILE* fpOut;
rv_depack* pDepack;
rv_decode* pDecode;
BYTE* pOutFrame;
UINT32 ulOutFrameSize;
UINT32 ulWidth;
UINT32 ulHeight;
UINT32 ulNumInputFrames;
UINT32 ulNumOutputFrames;
} rm2yuv_info;
static long numOfRVOut = 0;
//-----------------------
static HX_RESULT retVal = HXR_OK;
static MY_FILE* fp = HXNULL;
static INT32 lBytesRead = 0;
static UINT32 ulNumStreams = 0;
static UINT32 i = 0;
static UINT16 usStreamNum_v = (-1);
static UINT32 ulOutFrameSize = 0;
static UINT32 ulFramesPerSec = 0;
static UINT32 ulRIFFSizeOff = 0;
static UINT32 ulTotFramesOff = 0;
static UINT32 ulStrHdrLenOff = 0;
static UINT32 ulMoviLenOff = 0;
static UINT32 ulHdrLen = 0;
static BYTE* pOutFrame = HXNULL;
static BYTE* pTmp = HXNULL;
static UINT32 ulPixels = 0;
static rm_parser* pParser = HXNULL;
static rm_stream_header* pHdr_v = HXNULL;
static rm_packet* pPacket = HXNULL;
static rv_depack* pDepack_v = HXNULL;
static rv_decode* pDecode_v = HXNULL;
static rv_format_info* pInfo_v = HXNULL;
static rm2yuv_info info_v;
static BYTE ucBuf[RM2YUV_INITIAL_READ_SIZE];
static UINT32 ulCodec4CC = 0;
static UINT32 ulTmp = 0;
static BYTE ucTmp[68];
static UINT32 ulAbr = 0;
static UINT32 ulCurrentTime = 0;
static UINT32 CurrentRealVideoVersion;
static UINT32 TotalTimeLength = 0;
//回调函数,由解包器适时调用
/******************************************************
Name: rv_frame_available
Desc: RV帧可用回调函数
Param: pAvail 解码结构体指针
ulSubStream 流编号
pFrame 视频帧指针
Return: HXR_FAIL-失败 HXR_OK-成功
Global: 无
Note: 无
Author: Vincent Hisung
Log:
/******************************************************/
HX_RESULT rv_frame_available(void* pAvail, UINT32 ulSubStreamNum, rv_frame* pFrame)
{
return HXR_OK;
}
/******************************************************
Name: rm2yuv_error
Desc: RV块解包错误回调函数
Param: pError 出错结构体指针
result 结果
pszMsg 信息
Return: 无
Global: 无
Note: 无
Author: Vincent Hisung
Log:
/******************************************************/
void rm2yuv_error(void* pError, HX_RESULT result, const char* pszMsg)
{
}
void PackRVFormatInfo(rv_format_info* pInfo, BYTE* pBuf, UINT32 ulLen)
{
if (pInfo && pBuf && ulLen >= pInfo->ulLength)
{
rm_pack32(pInfo->ulLength, &pBuf, &ulLen);
rm_pack32(pInfo->ulMOFTag, &pBuf, &ulLen);
rm_pack32(pInfo->ulSubMOFTag, &pBuf, &ulLen);
rm_pack16(pInfo->usWidth, &pBuf, &ulLen);
rm_pack16(pInfo->usHeight, &pBuf, &ulLen);
rm_pack16(pInfo->usBitCount, &pBuf, &ulLen);
rm_pack16(pInfo->usPadWidth, &pBuf, &ulLen);
rm_pack16(pInfo->usPadHeight, &pBuf, &ulLen);
rm_pack32(pInfo->ufFramesPerSecond, &pBuf, &ulLen);
/* Sanity Check */
if (ulLen >= pInfo->ulOpaqueDataSize)
{
memcpy(pBuf, pInfo->pOpaqueData, pInfo->ulOpaqueDataSize);
}
}
}
long GetRVBufDataLen()
{
return cur_RV_SliceDataLen;
}
unsigned long GetRVCurTime()
{
return ulCurrentTime;
}
long GetRVWidth()
{
return info_v.ulWidth ;
}
void RVSeek(unsigned long time_pos)
{
seek_time = time_pos ;
//rm_parser_seek(pParser,time_pos);
}
int GetIsSeeking()
{
if (seeked_time/*seek_time=*/ != (-1))
{
return 0;
}
else
{
return 1;
}
}
unsigned long GetRVSeekedTime()
{
return seeked_time;
}
long GetRVHeight()
{
return info_v.ulHeight ;
}
long GetRVData(char *dst, long len)
{
if (len < cur_RV_SliceDataLen)
{
memcpy(dst, &RV_SliceDataBuf[0], len);
memcpy(&RV_SliceDataBuf[0], &RV_SliceDataBuf[len], cur_RV_SliceDataLen - len + 1);
cur_RV_SliceDataLen -= len;
return len;
}
else
{
memcpy(dst, &RV_SliceDataBuf[0], cur_RV_SliceDataLen);
cur_RV_SliceDataLen = 0;
return cur_RV_SliceDataLen;
}
}
static int isSetTimestampTo0 = 0;
void RVSetOutTimestampTo0(int isTrue)
{
if (isTrue == 1)
isSetTimestampTo0 = 1;
else
isSetTimestampTo0 = 0;
}
unsigned long Real_GetCurrentVideoSliceTime(void)
{
return ulCurrentTime;
}
void FillRVEnd()
{
while (cur_RV_SliceDataLen < RV_SLICEDATABUF_SIZE - 8)
{
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'R';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'E';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'A';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'L';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'V';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ' ';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 0xff;
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 0xff;
}
}
int volatile isCanBeSeek = 0;
void SEND_IT(rv_depack_internal* pInt, unsigned long len, unsigned int type, unsigned int timestamp)
{
//In fact,if I check the ECC packet and drop it may occour the stream has not end packet..
//So the wisdom is to check ECC in DSP, not here
//By Vincent Hisung,Nov 5,2007
if ((pInt->pCurFrame->pData[0]&pDecode_v->ulECCMask) == 0) // This check whether it is ECC packet. By Vincent Hisung
{
if (type != 2)
ulCurrentTime = timestamp;
//The Time After Seek
if (seeked_time == (-1))
{
seeked_time = timestamp;
RVSetOutTimestampTo0(0);
}
if (isSetTimestampTo0 == 1)
{
timestamp = 0;
}
/*
fwrite(&type , 2, 1, info_v.fpOut); //type
fwrite(&len , 4, 1, info_v.fpOut); //len
fwrite(×tamp , 4, 1, info_v.fpOut); //timestamp
//*/
//fwrite(pInt->pCurFrame->pData, 1, len, info_v.fpOut); //data
//printf("RV out: %i , type : %i ,timestamp: %i \n",len,type,timestamp);
numOfRVOut = len + 2 + 4 + 4;
/*
*((short *)&RV_SliceDataBuf[cur_RV_SliceDataLen])=type;
cur_RV_SliceDataLen+=2;
*((long *)&RV_SliceDataBuf[cur_RV_SliceDataLen])=len;
cur_RV_SliceDataLen+=4;
*((long *)&RV_SliceDataBuf[cur_RV_SliceDataLen])=timestamp;
cur_RV_SliceDataLen+=4;
*/
/*
RV_SliceDataBuf[cur_RV_SliceDataLen++]=(type&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((type>>8)&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((len)&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((len>>8)&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((len>>16)&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((len>>24)&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((timestamp)&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((timestamp>>8)&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((timestamp>>16)&0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++]=((timestamp>>24)&0xff);
*/
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'R';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'E';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'A';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'L';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = 'V';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ' ';
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((type >> 8) & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = (type & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((len >> 24) & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((len >> 16) & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((len >> 8) & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((len) & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((timestamp >> 24) & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((timestamp >> 16) & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((timestamp >> 8) & 0xff);
RV_SliceDataBuf[cur_RV_SliceDataLen++] = ((timestamp) & 0xff);
memcpy(&RV_SliceDataBuf[cur_RV_SliceDataLen], pInt->pCurFrame->pData, len);
//if Len is Odd, make it be Even
//By Vincent Hisung,Nov 6,2007
if (len & 0x01)
len++;
//------------------------------
cur_RV_SliceDataLen += len;
}
else
{
//printf("This is ECC Packet. %i\n",pInt->pCurFrame->pData[0]);
}
if ((type == 2) || (type == 3))
{
isCanBeSeek = 1;
#if 0
if (seek_time != (-1))
{
rm_parser_seek(pParser, seek_time);
seek_time = (-1);
seeked_time = (-1);
//RVFillBuf();
}
#endif
}
else
{
isCanBeSeek = 0;
}
}
HX_RESULT rm_parseri_search_index_chunk(void* pInt, UINT32 ulSeekTime);
int RVDecInit(MY_FILE* in)
{
pOutFrame = HXNULL;
pTmp = HXNULL;
ulPixels = 0;
pParser = HXNULL;
pHdr_v = HXNULL;
pPacket = HXNULL;
pDepack_v = HXNULL;
pDecode_v = HXNULL;
pInfo_v = HXNULL;
real_is_V_or_A = 0;
rv_seekable = 0;
fp = (MY_FILE*)in;//pRawFileCache;
/* NULL out the info_v */
info_v.fpOut = HXNULL;
info_v.pDepack = HXNULL;
info_v.pDecode = HXNULL;
info_v.pOutFrame = HXNULL;
info_v.ulOutFrameSize = 0;
info_v.ulNumInputFrames = 0;
info_v.ulNumOutputFrames = 0;
/* Assign the output file pointer */
info_v.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, RM2YUV_INITIAL_READ_SIZE);//MOD BY VINCENT
if (lBytesRead != RM2YUV_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, RM2YUV_INITIAL_READ_SIZE))
{
//非RM文件
goto cleanup;
}
/* Create the parser struct */
pParser = rm_parser_create(NULL, rm2yuv_error);
if (!pParser)
{
goto cleanup;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -