⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prmdec_v.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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(&timestamp , 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 + -