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

📄 mpeg.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
字号:

/* mpeg.c, main(), initialization, option processing                    */


//#include <stdio.h>
//#include <stdlib.h>
#include <ctype.h>
//#include <fcntl.h>
#include <string.h>

#define GLOBAL
#include "mpg_config.h"
#include "mpg_global.h"

/* private prototypes */
static int  Headers _ANSI_ARGS_((void));
int MpegVideoReadData(char *buffer, int size);
extern int Get_Seq_Hdr();

static void Set_Options();

#if 0
int main(argc, argv)
int argc;
char *argv[];
{
    int code, i = 0, readSize;
    char filename[300];
    FILE *pfVideoOut;
    char bitsBfr[4096];

    Set_Options();

    if (argc > 1)
    {
        /* open MPEG base layer bitstream file(s) */
        /* NOTE: this is either a base layer stream or a spatial enhancement stream */
        base.Infile = fopen(argv[1], "rb");
        if (!base.Infile)
        {
            fprintf(stderr, "Base layer input file %s not found\n", argv[1]);
            exit(1);
        }
        Main_Bitstream_Filename = argv[1];
    }
    else
    {
        printf("Usage: mpeg2decode Options: file \n");
        exit(0);
    }

    ld = &base; /* select base layer context */

    if (base.Infile != 0)
    {
        Initialize_Buffer();

        if (Show_Bits(8) == 0x47)
        {
            sprintf(Error_Text, "Decoder currently does not parse transport streams\n");
            Error(Error_Text);
        }

        next_start_code();
        code = Show_Bits(32);

        switch (code)
        {
            case SEQUENCE_HEADER_CODE:
                break;
            case PACK_START_CODE:
                System_Stream_Flag = 1;
            case VIDEO_ELEMENTARY_STREAM:
                System_Stream_Flag = 1;
                break;
            default:
                sprintf(Error_Text, "Unable to recognize stream type\n");
                Error(Error_Text);
                break;
        }

    }

    fseek(base.Infile, 0l, SEEK_SET);

    ld->Incnt = 0;
    ld->Rdptr = ld->Rdbfr + 2048;
    ld->Rdmax = ld->Rdptr;

    //  Get_Hdr();

    if (System_Stream_Flag)
    {
        sprintf(filename, "%s_demux.vid", Main_Bitstream_Filename);
        pfVideoOut = fopen(filename, "wb");

        while (!feof(base.Infile))
        {
#if 1
            if (readSize = MpegVideoReadData(bitsBfr, 4096))
            {
                fwrite(bitsBfr, 1, readSize, pfVideoOut);
                if ((++i) == 3811)
                    i = 0;
                if (readSize < 4096)
                    break;
            }
            else
            {
                break;
            }
#else
            Next_Packet();
            if ((ld->Rdbfr[0] == SEQUENCE_END_CODE >> 24)
                    && (ld->Rdbfr[1] = SEQUENCE_END_CODE >> 16)
                    && (ld->Rdbfr[2] = SEQUENCE_END_CODE >> 8)
                    && (ld->Rdbfr[3] = SEQUENCE_END_CODE & 0xff))
                break;
            if (ld->Rdmax > ld->Rdbfr + 2048)
            {
                fwrite(ld->Rdptr, 1, ld->Rdbfr + 2048 - ld->Rdptr, pfVideoOut);

                while ((ld->Rdmax - (ld->Rdbfr + 2048)) > 2048)
                {
                    fread(ld->Rdbfr, 1, 2048, ld->Infile);
                    fwrite(ld->Rdbfr, 1, 2048, pfVideoOut);
                    ld->Rdmax -= 2048;
                }
                fread(ld->Rdbfr, 1, (ld->Rdmax - (ld->Rdbfr + 2048)), ld->Infile);
                fwrite(ld->Rdbfr, 1, (ld->Rdmax - (ld->Rdbfr + 2048)), pfVideoOut);

                ld->Rdptr = ld->Rdbfr + 2048;
            }
            else
            {
                fwrite(ld->Rdptr, 1, ld->Rdmax - ld->Rdptr, pfVideoOut);
                ld->Rdptr = ld->Rdmax;
            }

#endif
        }
    }
    //ret = Decode_Bitstream();

    fclose(base.Infile);
    fclose(pfVideoOut);
    return 0;
}
#endif

static __inline void MpegGetDuration()
{
    int sizeToGetDur = 204800;

    //dts_orig = pts_orig = 0;
    mpeg.startTime = 0;
    pts_dts_orig_flag = 0;

    fseek(base.Infile, 0, SEEK_SET);
    Initialize_Buffer(ld);
    while ((pts_dts_orig_flag == 0) && (!Fault_Flag))
        Headers();

    fseek(base.Infile, 0, SEEK_END);
    mpeg.filesize = ftell(base.Infile);

retry:
    Fault_Flag = 0;
    sizeToGetDur += 102400;
    if ((sizeToGetDur != 204800) && (sizeToGetDur > 2048000))
        return;
    if (mpeg.filesize > sizeToGetDur)
        fseek(base.Infile, mpeg.filesize - sizeToGetDur, SEEK_SET);
    else
        fseek(base.Infile, 0, SEEK_SET);

    Initialize_Buffer(ld);
    if (Fault_Flag)
    {
        goto retry;
    }

    while (!Fault_Flag)
        Headers();
    if (mpeg.curTime == mpeg.startTime)
    {
        goto retry;
    }

    mpeg.duration = mpeg.curTime - mpeg.startTime;
}


int MpegDemuxInit(FILE *pfMain)
{
    int code, i = 0, seq_flag = 0;

    Set_Options();

    base.Infile = pfMain;

    ld = &base;

    System_Stream_Flag = 0;
    Fault_Flag = 0;

    Initialize_Buffer(ld);

    if (Show_Bits(ld, 8) == 0x47)
    {
        Fault_Flag = 1;
        return -1;
    }

    do
    {
        next_start_code(ld);
        code = Show_Bits(ld, 32);

        switch (code)
        {
            case SEQUENCE_HEADER_CODE:
                seq_flag = 1;
                //return 1;
                break;
            case PACK_START_CODE:
                System_Stream_Flag = 1;
            case VIDEO_ELEMENTARY_STREAM:
                System_Stream_Flag = 1;
                break;
            default:
                Flush_Buffer32(ld);
                //Fault_Flag = 1;
                //return 1;
                break;
        }

        if (seq_flag)  /* we have seq header */
            break;
        else if (i++ > 3)
            return 1;
    }
    while (!System_Stream_Flag);

    if (System_Stream_Flag)
    {
        MpegGetDuration();
        Fault_Flag = 0;
    }

    mpeg.curTime = 0;
    fseek(base.Infile, 0l, SEEK_SET);
    Initialize_Buffer(ld);
    if (!Get_Seq_Hdr())
        return -1;

    if (!Get_Hdr())
        return -1;

    /* check chroma format */
    if (chroma_format && (chroma_format != CHROMA420))
        return -1;
   // if (ld->MPEG2_Flag)
     //   return -1;

    ld->Incnt = 0;
    ld->Rdptr = ld->Rdbfr + 2048;
    ld->Rdmax = ld->Rdptr;
    fseek(base.Infile, 0l, SEEK_SET);
    mpeg.curTime = 0;

    return 0;
}

int MpegDemuxAudioInit(FILE *pfMain)
{
    if (!System_Stream_Flag)
        return 0;

    audiobase.Infile = pfMain;
    ld2 = &audiobase;
    Fault_Flag = 0;

    fseek(audiobase.Infile, 0l, SEEK_SET);
    Initialize_Buffer(ld2);
    Next_PacketAudio();
    /*    pfAuBits = fopen("D:\\audio.mp2", "wb" );
        while(1){
            if(MpegAudioGetDataToSDRAM(&mpeg, buffer, 2048) < 2048)
                break;
            RKFSFileWrite(buffer, 2048, pfAuBits);
        }
        RKFSFileClose(pfAuBits);*/
    fseek(audiobase.Infile, 0l, SEEK_SET);
    Initialize_Buffer(ld2);
    return 0;
}

int MpegVideoCheckFrameEnd(char *buffer, int fromPos, int endpos)
{
    int i, codeword = 0xffffffff;
    for (i = fromPos; i < endpos; i++)
    {
        codeword = (codeword << 8) | (buffer[i]);
        if (codeword == PICTURE_START_CODE)//SEQUENCE_HEADER_CODE)//||codeword==GROUP_START_CODE||codeword==PICTURE_START_CODE)
            break;
    }
    if (i == endpos)
        i = -1;
    return i;   //(i > 4)?(i - 4):0;
}

int MpegVideoReadData(char *buffer, int size)
{
    static int skipcnt = 0;
    int getBytes = 0, endPos, fromPos;
    int i;
    double skiplen;

    if (!System_Stream_Flag)
    {
        getBytes += fread(&buffer[getBytes], 1, size, ld->Infile);
        return getBytes;
    }
    while (1)
    {
        if ((ld->Rdptr >= ld->Rdmax))
        {
            Next_Packet(0);
            while (ld->Rdptr >= ld->Rdbfr + 2048)
            {
                if (fread(ld->Rdbfr, 1, 2048, ld->Infile) < 2048)
                {
                    Fault_Flag = 1;
                }
                ld->Rdptr -= 2048;
                ld->Rdmax -= 2048;
            }
            if (Fault_Flag)
                return getBytes;
        }
        if (size <= (ld->Rdmax - ld->Rdptr))
        {
            fromPos = getBytes;
            if (((ld->Rdmax >= ld->Rdbfr + 2048) && (size <= (ld->Rdbfr + 2048 - ld->Rdptr)))
                    || (ld->Rdmax < ld->Rdbfr + 2048))
            {
                memcpy(&buffer[getBytes], ld->Rdptr, size);
                getBytes += size;
                ld->Rdptr += size;
            }
            else
            {
                memcpy(&buffer[getBytes], ld->Rdptr, (ld->Rdbfr + 2048 - ld->Rdptr));
                getBytes += (ld->Rdbfr + 2048 - ld->Rdptr);
                size -= (ld->Rdbfr + 2048 - ld->Rdptr);
                ld->Rdptr = ld->Rdbfr + 2048;

                fread(&buffer[getBytes], 1, size, ld->Infile);
                getBytes += size;
                ld->Rdmax -= size;
            }
            size -= size;
            if (mpeg.skipFlag == MPEG_SKIP_FLAG_END)
            {
                goto seek_to;
            }
            else
            {
                return getBytes;
            }
        }
        else
        {
            fromPos = getBytes;
            if (ld->Rdmax > ld->Rdbfr + 2048)
            {
                memcpy(&buffer[getBytes], ld->Rdptr, (ld->Rdbfr + 2048 - ld->Rdptr));
                getBytes += (ld->Rdbfr + 2048 - ld->Rdptr);
                size -= (ld->Rdbfr + 2048 - ld->Rdptr);
                ld->Rdptr = ld->Rdbfr + 2048;

                fread(&buffer[getBytes], 1, ld->Rdmax - (ld->Rdbfr + 2048), ld->Infile);
                getBytes += ld->Rdmax - (ld->Rdbfr + 2048);
                size -= ld->Rdmax - (ld->Rdbfr + 2048);
                ld->Rdmax = ld->Rdptr;

            }
            else
            {
                memcpy(&buffer[getBytes], ld->Rdptr, (ld->Rdmax - ld->Rdptr));
                getBytes += (ld->Rdmax - ld->Rdptr);
                size -= (ld->Rdmax - ld->Rdptr);
                ld->Rdptr = ld->Rdmax;
            }

            if (mpeg.skipFlag == MPEG_SKIP_FLAG_END)
            {
                goto seek_to;
            }
            else
            {
                continue;
            }
        }

seek_to:
        if ((endPos = MpegVideoCheckFrameEnd(buffer, fromPos, getBytes)) > 0)
        {
            if (mpeg.duration > 0)
            {
                skiplen = (double)mpeg.seekTime * mpeg.filesize / mpeg.duration;
                ld->Rdptr = ld->Rdbfr + 2048;
                ld->Rdmax = ld->Rdptr;
                ld->Incnt = 0;
                fseek(ld->Infile, skiplen, SEEK_SET);
                mpeg.curTime = mpeg.seekTime;
                Get_GOP_Hdr();
                buffer[endPos] = 0xb8;
                size += (getBytes - endPos - 1);
                getBytes = endPos + 1;
                MpegSynAudio2Video(&mpeg);
            }
            mpeg.skipFlag = MPEG_SKIP_FLAG_NONE;
        }
        else if (size == 0)
            return getBytes;
    }
}

int MpegAudioGetDataToSDRAM(MpegDemux *mpeg, char *buffer, DWORD size)
{
    int getBytes = 0;

    if (!System_Stream_Flag)
    {
        getBytes += fread(&buffer[getBytes], 1, size, ld2->Infile);
        goto get_end;
    }

    while (1)
    {
        if ((ld2->Rdptr >= ld2->Rdmax))
        {
            Next_PacketAudio();
            while (ld2->Rdptr >= ld2->Rdbfr + 2048)
            {
                if (fread(ld2->Rdbfr, 1, 2048, ld2->Infile) < 2048)
                {
                    Fault_Flag = 1;
                }
                ld2->Rdptr -= 2048;
                ld2->Rdmax -= 2048;
            }
            if (Fault_Flag)
                goto get_end;
        }
        if (size <= (ld2->Rdmax - ld2->Rdptr))
        {
            if (((ld2->Rdmax >= ld2->Rdbfr + 2048) && (size <= (ld2->Rdbfr + 2048 - ld2->Rdptr)))
                    || (ld2->Rdmax < ld2->Rdbfr + 2048))
            {
                memcpy(&buffer[getBytes], ld2->Rdptr, size);
                getBytes += size;
                ld2->Rdptr += size;
            }
            else
            {
                memcpy(&buffer[getBytes], ld2->Rdptr, (ld2->Rdbfr + 2048 - ld2->Rdptr));
                getBytes += (ld2->Rdbfr + 2048 - ld2->Rdptr);
                size -= (ld2->Rdbfr + 2048 - ld2->Rdptr);
                ld2->Rdptr = ld2->Rdbfr + 2048;

                fread(&buffer[getBytes], 1, size, ld2->Infile);
                getBytes += size;
                ld2->Rdmax -= size;
            }
            size -= size;
            goto get_end;
        }
        else
        {
            if (ld2->Rdmax > ld2->Rdbfr + 2048)
            {
                memcpy(&buffer[getBytes], ld2->Rdptr, (ld2->Rdbfr + 2048 - ld2->Rdptr));
                getBytes += (ld2->Rdbfr + 2048 - ld2->Rdptr);
                size -= (ld2->Rdbfr + 2048 - ld2->Rdptr);
                ld2->Rdptr = ld2->Rdbfr + 2048;

                fread(&buffer[getBytes], 1, ld2->Rdmax - (ld2->Rdbfr + 2048), ld2->Infile);
                getBytes += ld2->Rdmax - (ld2->Rdbfr + 2048);
                size -= ld2->Rdmax - (ld2->Rdbfr + 2048);
                ld2->Rdmax = ld2->Rdptr;
            }
            else
            {
                memcpy(&buffer[getBytes], ld2->Rdptr, (ld2->Rdmax - ld2->Rdptr));
                getBytes += (ld2->Rdmax - ld2->Rdptr);
                size -= (ld2->Rdmax - ld2->Rdptr);
                ld2->Rdptr = ld2->Rdmax;
            }
        }
    }

get_end:
    Fault_Flag = 0;
    return getBytes;
}

void Error(void)
{
    Fault_Flag = 1;
}

static int Headers()
{
    int ret;

    ld = &base;


    /* return when end of sequence (0) or picture
       header has been parsed (1) */

    ret = Get_Hdr();

    return ret;
}

static void Set_Options()
{
#ifdef VERBOSE
    Verbose_Flag = 7;
#endif

    Fault_Flag = 0;
    System_Stream_Flag = 0;

    chroma_format = 0;
}


⌨️ 快捷键说明

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