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

📄 avifile.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************************
 Copyright (C), 2007, Fuzhou Rockchip Co.,Ltd.
 File:
  AviFile.c
 Description:
  Parse and demux AVI file.
 Note:
  None.
 Author:
  ljn
 $Log: AviFile.c,v $
 Revision 1.7  2008/07/08 12:50:42  HZF
 增加PCM解码

 Revision 1.6  2008/06/19 04:42:31  Administrator
 代码整理!

 Revision 1.5  2008/06/13 08:44:42  HZF
 总帧数不对的片源处理

 Revision 1.4  2008/06/04 09:55:58  HZF
 Seek时间不准问题

 Revision 1.3  2008/05/30 09:47:25  HZF
 avibug

 Revision 1.2  2008/05/20 12:00:56  HZF
 avi文件播放提交

 Revision 1.1.1.1  2008/05/07 04:14:50  Administrator
 no message

 Revision 1.1.1.1  2008/03/06 13:28:26  Lingzhaojun
 no message

 Revision 1.4  2007/12/11 12:13:47  Huangzufang
 video提交

 Revision 1.3  2007/11/21 10:12:41  Linjiangnan
 *** empty log message ***

 Revision 1.1  2007/11/16 14:43:19  Huangxinyu
 提交ljn的video

********************************************************************************************/
#define _IN_AVIFILE_H

#include "system.h"
#include "AviFile.h"

CurChunk videoChunkSkipTo;
unsigned int beingSkip, audioChunkNum, audioTimePerChunk, NDCodeRemain, moviCkSize, skipResume, audioBytePos, lastSkipPoint, audioSteamID;
char NDCode[] = {0xb7, 0x01, 0x00, 0x00};
idx1 chunkList[AVI_CHUNK_LIST_NUM];
unsigned long indexSize;

extern int isAudioPlayEnd;
/********************************************************************************************
 Func:
  AviSeek()
 Description:
  Seek the AVI file for a requested chunk .
 Param:
  MY_FILE *file - pointer of avi file.
  FOURCC ckID - sign of chunk to seek.
 Return:
  0:  Fail.
  >1: Size of the chunk.
 Author:
  ljn
 Date:
  2007-9-17 15:38
 Log:

********************************************************************************************/
#if 0
int AviSeek(MY_FILE *file, FOURCC ckID)
{
    struct
    {
        FOURCC CkID;
        DWORD Size;
    } chunk;

    if (AviFread(&chunk, sizeof(chunk), 1, file) < sizeof(chunk))
        return 0;
    while (chunk.CkID != ckID)
    {
        AviFseek(file, chunk.Size, SEEK_CUR);
        if (AviFread(&chunk, sizeof(chunk), 1, file) < sizeof(chunk))
            return 0;
    }
    return chunk.Size;
}
#else
int AviSeek(MY_FILE *file, FOURCC ckID)
{
    int timeOut = 0;
    struct
    {
        FOURCC CkID;
        DWORD Size;
    } chunk;

    if (AviFread(&chunk, sizeof(chunk), 1, file) < sizeof(chunk))
        return 0;
    while (chunk.CkID != ckID)
    {

        /* skip chunk. */
        AviFseek(file, chunk.Size, SEEK_CUR);

        /* read chunk head. */
        if (AviFread(&chunk, sizeof(chunk), 1, file) < sizeof(chunk))
            return 0;

        chunk.Size += (chunk.Size & 0x1);    //NOTICE: 2-align@jianhuan
        /* time out control. */
        if ((timeOut++) > 1000)
            return 0;
    }
    return chunk.Size;
}
#endif

/********************************************************************************************
 Func:
  AviGetChunkPointer()
 Description:
  Get file pointer of chunks.
 Param:
  MY_FILE *file - pointer of avi file.
  FOURCC ckID - sign of chunk to seek (only hdrl, movi and idx1 is supported).
 Return:
  0:  OK.
  -1: failed.
 Author:
  ljn
 Date:
  2007-12-07 13:38
 Log:

********************************************************************************************/
int AviGetChunkPointer(AVI_FILE *file, FOURCC ckID)
{
    DWORD riffType;
    struct
    {
        FOURCC CkID;
        DWORD Size;
        DWORD Type;
    } list;

    AviFseek(file, 0, SEEK_SET);

    /* Check if it is a riff file. */
    if (!AviSeek(file, SIGN_RIFF))
        return -1;
    if (AviFread(&riffType, 1, sizeof(riffType), file) < sizeof(riffType))
        return -1;

    /* Check if it is a avi riff file. */
    if (riffType != SIGN_AVI_)
        return -1;

    switch (ckID)
    {
        case SIGN_IDX1:
            {
                /* Seek 'idx1'. */
                if ((indexSize = AviSeek(file, ckID)) == 0)
                    return -1;
            }
            break;

        case SIGN_HDRL:
        case SIGN_MOVI:
            {
                /* Find list. */
                if (AviFread(&list, 1, sizeof(list), file) < sizeof(list))
                    return -1;
                list.Size += (list.Size & 0x1); //NOTICE: 2-align @ jianhuan
                while (list.Type != ckID)
                {
                    AviFseek(file, list.Size - 4, SEEK_CUR);
                    if (AviFread(&list, 1, sizeof(list), file) < sizeof(list))
                        return -1;
                }
                if (list.Type == SIGN_MOVI)
                    moviCkSize = list.Size;
            }
            break;

        default:
            return -1;
    }
    return 0;
}


/********************************************************************************************
 Func:
  AviCreateSeekTab()
 Description:
  Create seek table.
 Param:
  AviFilePointer *aviPointer - avi file pointer.
  unsigned int idx1Size - index size.
 Return:
  0:  OK.
  -1: failed.
 Author:
  ljn
 Date:
  2007-12-07 13:38
 Log:

********************************************************************************************/
extern char gVideoBufferMix[];

int AviCreateSeekTab(AviFilePointer *aviPointer, unsigned int idx1Size)
{
    idx1 *indexBuf;
    unsigned int i, j = 0, audioCkNum = 0, videoCkNum = 0, totalCkNum = 0, keyFrmNum = 0, audioByteNum = 0;
    unsigned int bufSize = (0x20000 * sizeof(idx1)), ckNumRead = 0x200000, audioInfoStep = 0;
    int  readSize;

    /* buffer initialize */
#if 0
    keyFrameList = (KeyFrame *)MALLOC(6000 * (sizeof(KeyFrame)));
    indexBuf = (idx1 *)MALLOC(bufSize);
#else
    keyFrameList = (KeyFrame *)(gVideoBufferMix + SYSCFG_VIDEOBUF_LEN - 6000 * (sizeof(KeyFrame)));

    /* temporary buffer for avi index, this buffer will be used as yuv buffer affter decoder is started. */
    indexBuf = (idx1 *)gVideoBufferMix;
#endif

    /* Get step length to save audio information. */
    if (audioChunkNum < AVI_AUDIO_POS_INFO_NUM)
        audioInfoStep = 1;
    else
        audioInfoStep = (audioChunkNum >> 6) + 1;

    for (;idx1Size > 0; idx1Size -= readSize)
    {

        /* Read index */
        if (idx1Size > bufSize)
        {
            readSize = AviFread(indexBuf, 1, bufSize, aviPointer->VideoIndex);
        }
        else
        {
            readSize = AviFread(indexBuf, 1, idx1Size, aviPointer->VideoIndex);
        }

        if (readSize <= 0)
            break;

        ckNumRead = readSize / (sizeof(idx1));

        /* create table. */
        for (i = 0; i < ckNumRead; i++)
        {
            totalCkNum ++;
            if (IS_VIDEO_IDX(indexBuf[i].dwChunkid))
            {
                /* video index. */
                videoCkNum ++;
                if ((indexBuf[i].dwFlags & 0x00000010) == 0x10)         /* save key frame information. */
                {
                    keyFrameList[keyFrmNum].dwSize = indexBuf[i].dwSize;
                    keyFrameList[keyFrmNum].dwOffset = indexBuf[i].dwOffset;
                    if (stream_supported_flag.VideoCodecLib == VIDEO_CODEC_LIB_DIV3)
                    {
                        keyFrameList[keyFrmNum].dwSize   += (8 + (indexBuf[i].dwSize & 0x1));   //将00dc和chunk size计算在内;
                        keyFrameList[keyFrmNum].dwOffset -= 8;
                    }
                    else if (stream_supported_flag.VideoCodecLib == VIDEO_CODEC_LIB_MJPG)
                    {
                        keyFrameList[keyFrmNum].dwSize   += (4 + (indexBuf[i].dwSize & 0x1));   //将00dc和chunk size计算在内;
                        keyFrameList[keyFrmNum].dwOffset -= 4;
                    }
                    keyFrameList[keyFrmNum].dwNumber = totalCkNum;
                    keyFrameList[keyFrmNum].dwVideoFrameNum = videoCkNum;
                    keyFrmNum++;
                }
#ifdef ON_RKFS
                if ((videoCkNum % (avih.dwTotalFrames / AVI_VIDEO_POS_INFO_NUM + 1)) == 0)  /* save video positon information. */
                {
                    j = videoCkNum / (avih.dwTotalFrames / AVI_VIDEO_POS_INFO_NUM + 1);
                    AviFseek(aviPointer->VideoData, (long)(indexBuf[i].dwOffset + moviPos.Offset) - (long)(aviPointer->VideoData->Offset), SEEK_CUR);
                    videoDataPosInfo[j].Clus = aviPointer->VideoData->Clus;
                    videoDataPosInfo[j].Offset = aviPointer->VideoData->Offset;
                }
            }
            else if ((stream_supported_flag.AudioSupportedFlag == TRUE) && (IS_AUDIO_NO1_IDX(indexBuf[i].dwChunkid)))     //jianhuan
            {
                /* audio index. save audio pos info for fast positioning. */
                audioCkNum ++;
                audioByteNum += indexBuf[i].dwSize;
                /*     if((audioCkNum % (audioInfoStep)) == 0){
                         j = (audioCkNum)/(audioInfoStep);*/
                j = (audioCkNum) / (audioInfoStep);
                if ((j < AVI_AUDIO_POS_INFO_NUM) && (audioCkNum % (audioInfoStep)) == 0)
                {




                    /* seek to current index pos. */
                    AviFseek(aviPointer->AudioIndex, (long)(totalCkNum * sizeof(idx1) + idx1Pos.Offset) - (long)(aviPointer->AudioIndex->Offset), SEEK_CUR);

                    /* save file pointer and audio data information. */
                    audioIndexPosInfo[j].filePos.Clus = aviPointer->AudioIndex->Clus;
                    audioIndexPosInfo[j].filePos.Offset = aviPointer->AudioIndex->Offset;
                    audioIndexPosInfo[j].streamChunkNum = audioCkNum;
                    audioIndexPosInfo[j].audioBytePos = audioByteNum;
                }
#endif
            }
        }
    }

    /* Initialize key frame number. */
    totalKeyFrmNum = keyFrmNum;

    /* redress total frames. */
    avih.dwTotalFrames = videoCkNum;

    //FREE(keyFrameList);
    //FREE(indexBuf);

    return 0;
}

int AviIdxOffset(AVI_FILE *file)
{
    unsigned long tmpLong[4];

    memset(tmpLong, 0, 4*sizeof(unsigned long));
    AviFread(&tmpLong, 4*sizeof(unsigned long), 1, file);

    AviFseek(file, -4*sizeof(unsigned long), SEEK_CUR);

    if (tmpLong[0] == fcc7Fxx)
        return 1;

    return 0;
}
int IsOdmlAvi(AVI_FILE *AviIdxFile, AVI_FILE *AviVideoFile)
{
    FILE_POS    tmpIdxFile, tmpVideoFile;
    idx1        tmpIndex;
    int         readSize;
    FOURCC      tmpFcc;

    tmpIdxFile.Clus   = AviIdxFile->Clus;
    tmpIdxFile.Offset = AviIdxFile->Offset;

    tmpVideoFile.Clus   = AviVideoFile->Clus;
    tmpVideoFile.Offset = AviVideoFile->Offset;

    memset(&tmpIndex, 0, sizeof(idx1));

    do
    {
        readSize = AviFread(&tmpIndex, sizeof(tmpIndex), 1, AviIdxFile);
    }
    while (!IS_VIDEO_IDX(tmpIndex.dwChunkid));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -