flvfile.c

来自「瑞星微公司RK27XX系列芯片的SDK开发包」· C语言 代码 · 共 831 行 · 第 1/2 页

C
831
字号
            flv->curAudio.read = 0;
            return 0;
        }
        else
        {
            if ((tempBuf[4] != FLV_TAG_TYPE_VIDEO) && (tempBuf[4] != FLV_TAG_TYPE_SCRIPT))
                return -1;
            FlvFseek(flv->audioStr, size, SEEK_CUR);
        }
    }
}


int FlvVideoGetDataToSDRAM(FlvDemux *flv, char *buffer, DWORD *size)
{
    long i = 0, j, remainSize, sizeToGet = *size, tempReadSize;
    unsigned int timeStamp;

    remainSize = flv->curVideo.size - flv->curVideo.read;   //last chunk remain

    if ((flv->hdrRemain > 0) && (flv->hdrRemain <= FLV_HEADER_SIZE))
    {
        if (flv->hdrRemain <= sizeToGet)     // Read all remain frame header code to SDRAM
        {
            for (i = flv->hdrRemain; flv->hdrRemain > 0; flv->hdrRemain--)
            {
                buffer[i - flv->hdrRemain] = frmHdr[FLV_HEADER_SIZE - flv->hdrRemain];
            }
            sizeToGet -= i;
        }
    }

    if (remainSize > 0)
    {
        if (remainSize <= sizeToGet)     // Read all remain data to SDRAM
        {
            if (FlvFread(&buffer[i], remainSize, 1, flv->videoStr) < remainSize)
                return -1;
            sizeToGet -= remainSize;
            flv->curVideo.read = flv->curVideo.size;
        }
        else            // read size required to SDRAM
        {
            if (FlvFread(&buffer[i], sizeToGet, 1, flv->videoStr) < sizeToGet)
                return -1;
            flv->curVideo.read += sizeToGet;
            return 0;
        }
    }

//    tempReadSize = flv->curVideo.read;

    for (i = sizeToGet; i > 0; i -= flv->curVideo.read)
    {
        if (flv->skipFlag != FLV_SKIP_FLAG_NONE)
        {
            switch (flv->skipFlag)
            {
                case FLV_SKIP_FLAG_FFD:
                    if (FlvVideoGetNextKeyFrm(flv, 0))
                    {
                        if (i >= (*size))
                        {
                            return -1;
                        }
                        else
                        {
                            memset(&buffer[*size-i], 0, i);
                            return 0;
                        }
                    }
                    break;
                case FLV_SKIP_FLAG_FFW:
                    if (FlvVideoGetPreKeyFrm(flv, 0))
                        return -1;
                    break;
                case FLV_SKIP_FLAG_END:
                    FlvFseek(flv->videoStr, flv->keyFrm[flv->keyFrmNum].offset - 16, SEEK_SET);
                    flv->curVideo.read = flv->curVideo.size; ////
                    flv->videoFrmNum = flv->keyFrm[flv->keyFrmNum].frmID - 1;
                    flv->lastSkipPos = flv->videoFrmNum;
                    flv->keyFrmNum --;
                    if (FlvVideoGetNextFrmInfo(flv))
                        return -1;
                    OSSchedLock();
                    FlvSynAudio2Video(flv);
                    OSSchedUnlock();
                    break;
                default:
                    break;
            }
            flv->skipFlag = FLV_SKIP_FLAG_NONE;
        }
        else
        {
            if (FlvVideoGetNextFrmInfo(flv) < 0)
            {
                *size -= i;
                return -1;
            }
        }

#if 1
        //if((flvPlayState == FLV_STATE_FFD)||(flvPlayState == FLV_STATE_FFW))
        // timeStamp = 0;
        //else
        timeStamp = flv->curVideo.time;

        frmHdr[4] = (char)(timeStamp >> 24);
        frmHdr[5] = (char)(timeStamp >> 16);
        frmHdr[6] = (char)(timeStamp >> 8);
        frmHdr[7] = (char)(timeStamp);

        flv->hdrRemain = FLV_HEADER_SIZE;
        if (i <= FLV_HEADER_SIZE)
        {
            while (i > 0)
            {
                buffer[*size-i] = frmHdr[FLV_HEADER_SIZE - flv->hdrRemain];
                i --;
                flv->hdrRemain --;
            }
            return 0;
//            flv->curVideo.read = tempReadSize;
        }
        else
        {
            for (; flv->hdrRemain > 0; flv->hdrRemain --)
            {
                buffer[*size-i] = frmHdr[FLV_HEADER_SIZE - flv->hdrRemain];
                i --;
            }
            flv->curVideo.read = 0;
        }
#endif

//  flv->curVideo.read = tempReadSize;

        //FlvFseek(flv->videoStr, chunk.dwOffset-flv->Video->offset-flv->Video->read, SEEK_CUR);

        if (flv->curVideo.size <= (DWORD)i)
        {
            if (FlvFread(buffer + *size - i, flv->curVideo.size, 1, flv->videoStr) < flv->curVideo.size)
                return -1;
            flv->curVideo.read = flv->curVideo.size;
        }
        else
        {
            if (FlvFread(buffer + *size - i, i, 1, flv->videoStr) < i)
                return -1;
            flv->curVideo.read = i;
        }
//  tempReadSize = flv->curVideo.size;
    }

    return 0;
}


int FlvAudioGetDataToSDRAM(FlvDemux *flv, char *buffer, DWORD *size)
{
    long i, remainSize, sizeToGet = *size;

    remainSize = flv->curAudio.size - flv->curAudio.read;   //last chunk remain

    if (remainSize > 0)
    {
        if (remainSize <= sizeToGet)     // Read all remain data to SDRAM
        {
            if (FlvFread(buffer, remainSize, 1, flv->audioStr) < remainSize)
                return -1;
            sizeToGet -= remainSize;
            flv->curAudio.read = flv->curAudio.size;
        }
        else            // read size required to SDRAM
        {
            if (FlvFread(buffer, sizeToGet, 1, flv->audioStr) < sizeToGet)
                return -1;
            flv->curAudio.read += sizeToGet;
            sizeToGet = 0;
        }
    }

    for (i = sizeToGet; i > 0; i -= flv->curAudio.read)
    {
        if (FlvAudioGetNextFrmInfo(flv) < 0)
        {
            size -= i;
            return -1;
        }

        if (flv->curAudio.size <= (DWORD)i)
        {
            if (FlvFread(buffer + *size - i, flv->curAudio.size, 1, flv->audioStr) < flv->curAudio.size)
                return -1;
            flv->curAudio.read = flv->curAudio.size;
        }
        else
        {
            if (FlvFread(buffer + *size - i, i, 1, flv->audioStr) < i)
                return -1;
            flv->curAudio.read = i;
        }
    }
    return 0;
}

int FlvVideoGetNextKeyFrm(FlvDemux *flv, PacketInfo *frmInfo)
{
    char tempBuf[16];
    int  size;

    if (flv->curVideo.size > flv->curVideo.read)
    {
        FlvFseek(flv->videoStr, flv->curVideo.size - flv->curVideo.read, SEEK_CUR);
        flv->curVideo.read = flv->curVideo.size;
    }

    while (1)
    {
        if ((FlvFread(tempBuf, 1, 16, flv->videoStr)) != 16)  //[0]~[3]:PreviousTagSize
        {
            return -1;
        }

        size = ((unsigned long)tempBuf[5] << 16) | ((unsigned long)tempBuf[6] << 8) | ((unsigned long)tempBuf[7]);
        size -= 1;

        if ((tempBuf[4] == FLV_TAG_TYPE_VIDEO))
        {
            flv->videoFrmNum ++;

            if ((tempBuf[15] >> 4) == 0x01)  /* check if it is a key frame? */
            {

                /* video time stamp */
                flv->curVideo.time = ((unsigned long)tempBuf[11] << 24) | ((unsigned long)tempBuf[8] << 16) | ((unsigned long)tempBuf[9] << 8) | (unsigned long)tempBuf[10];

                flv->videoFrmNum ++;
                flv->keyFrmNum ++;
                flv->keyFrm[flv->keyFrmNum].offset = flv->videoStr->Offset;
                flv->keyFrm[flv->keyFrmNum].frmID = flv->videoFrmNum;

                flv->curVideo.type = tempBuf[0];
                flv->curVideo.size = size;
                flv->curVideo.read = 0;

                return 0;
            }

            FlvFseek(flv->videoStr, size, SEEK_CUR);

        }
        else
        {
            if ((tempBuf[4] != FLV_TAG_TYPE_VIDEO) && (tempBuf[4] != FLV_TAG_TYPE_AUDIO) && (tempBuf[4] != FLV_TAG_TYPE_SCRIPT))
            {
                return -1;
            }
            FlvFseek(flv->videoStr, size, SEEK_CUR);
        }
    }
}

int FlvVideoGetPreKeyFrm(FlvDemux *flv, PacketInfo *frmInfo)
{
    //if(flv->keyFrmNum <= 0)
    // return 0;

    if (!flv->lastSkipPos)
        flv->lastSkipPos = flv->videoFrmNum;
    else if (flv->lastSkipPos > 30)
        flv->lastSkipPos -= 30;

    if (flv->keyFrmNum > 0)
    {
        do
        {
            flv->keyFrmNum --;
        }
        while (((flv->keyFrm[flv->keyFrmNum].frmID >= flv->lastSkipPos)) && (flv->keyFrmNum > 0));
    }

    FlvFseek(flv->videoStr, flv->keyFrm[flv->keyFrmNum].offset - 16, SEEK_SET);
    flv->curVideo.read = flv->curVideo.size; ////
    flv->videoFrmNum = flv->keyFrm[flv->keyFrmNum].frmID - 1;
    flv->lastSkipPos = flv->videoFrmNum;
    flv->keyFrmNum --;
    if (FlvVideoGetNextFrmInfo(flv))
        return -1;
    frmHdr[4] = (char)(flv->curVideo.time >> 24);
    frmHdr[5] = (char)(flv->curVideo.time >> 16);
    frmHdr[6] = (char)(flv->curVideo.time >> 8);
    frmHdr[7] = (char)(flv->curVideo.time);

    flv->hdrRemain = FLV_HEADER_SIZE;
    return 0;
}

int FlvAudioSeek(FlvDemux *flv, long offset, int origin)
{
    if ((offset != 0) || (origin != 0))
        return 0;
    FlvFseek(flv->audioStr, flv->start, SEEK_SET);
    flv->curAudio.size = 0;
    flv->curAudio.read = 0;
    flv->curAudio.type = 0;
    flv->curAudio.time = 0;

    return 0;
}

int FlvFileOpen(FlvDemux *flv, char *path)
{
    flv->videoStr = FlvFopen(path, "rb");
    if ((int)flv->videoStr == -1 || !(int) flv->videoStr)
        return -1;

    flv->audioStr = FlvFopen(path, "rb");
    if ((int)flv->audioStr == -1 || !(int) flv->audioStr)
        return -1;
    return 0;
}

void FlvFileClose(FlvDemux *flv)
{
    if (flv->videoStr)
        FlvFClose(flv->videoStr);
    if (flv->audioStr)
        FlvFClose(flv->audioStr);
}

int FlvSeek(FlvDemux *flv, unsigned int time)
{
    if (time > 10000)
        time -= 10000;
    if (time > flv->curVideo.time)
    {
#if 1
        while (flv->curVideo.time < time)
        {
            if (FlvVideoGetNextFrmInfo(flv))
                return -1;
        }
#endif
        if (FlvVideoGetNextKeyFrm(flv, 0))
            return -1;

    }
    else if (time < flv->curVideo.time)
    {

        FlvFseek(flv->videoStr, flv->start, SEEK_SET);
        flv->curVideo.size = 0;
        flv->curVideo.read = 0;
        flv->curVideo.time = 0;

        while (flv->curVideo.time < time)
        {
            if (FlvVideoGetNextFrmInfo(flv))
                return -1;
        }
        if (FlvVideoGetNextKeyFrm(flv, 0))
            return -1;
    }
    //flv->skipFlag = FLV_SKIP_FLAG_SEEK;

    frmHdr[4] = (char)(flv->curVideo.time >> 24);
    frmHdr[5] = (char)(flv->curVideo.time >> 16);
    frmHdr[6] = (char)(flv->curVideo.time >> 8);
    frmHdr[7] = (char)(flv->curVideo.time);

    flv->hdrRemain = FLV_HEADER_SIZE;

    if (!time)
        FlvAudioSeek(flv, 0, 0);
    else
        FlvSynAudio2Video(flv);
    return 0;
}

int FlvSynAudio2Video(FlvDemux *flv)
{
#if 0
    if (flv->curAudio.time > flv->curVideo.time)
        FlvAudioSeek(flv, 0, SEEK_SET);

    while (flv->curAudio.time < flv->curVideo.time)
    {
        if (FlvAudioGetNextFrmInfo(flv))
            return -1;
    }
#else
    flv->audioStr->Clus = flv->videoStr->Clus;
    flv->audioStr->Offset = flv->videoStr->Offset;
    FlvFseek(flv->audioStr, flv->curVideo.size - flv->curVideo.read, SEEK_CUR);
    flv->curAudio.read = flv->curAudio.size;
#if 0
    flv->curAudio.time = flv->curVideo.time;
    flv->curAudio.read = flv->curAudio.size;
#else
    do
    {
        if (FlvAudioGetNextFrmInfo(flv) < 0)
        {
            return -1;
        }
    }
    while (flv->curAudio.time < flv->curVideo.time);
#endif

#endif
    return 0;
}

⌨️ 快捷键说明

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