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

📄 mpg_sys.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
字号:
/* systems.c, systems-specific routines                                 */


#include <stdio.h>
#include <stdlib.h>

#include "mpg_config.h"
#include "mpg_global.h"


/* initialize buffer, call once before first getbits or showbits */

static unsigned int mpeg_get_pts(layer_data *laydat, int c)
{

    unsigned int temp, pts;
    temp = c < 0 ? Get_Byte(laydat) : c;
    pts = (temp & 0x0e) << 29;
    temp = Get_Word(laydat);
    pts |= (temp >> 1) << 15;
    temp = Get_Word(laydat);
    pts |= (temp >> 1);

    return pts;
}

/* parse system layer, ignore everything we don't need */
void Next_Packet(int bskip)
{
    unsigned int code, len;
    int l;
    unsigned short temp, flags;
    unsigned int dts, pts;

    while (1)
    {
        code = Get_Long(ld);

        /* remove system layer byte stuffing */
        while ((code & 0xffffff00) != 0x100)
        {
            code = (code << 8) | Get_Byte(ld);
            if (Fault_Flag)
                return;
        }

        if (Fault_Flag)
            return;

        switch (code)
        {
            case PACK_START_CODE: /* pack header */
                /* skip pack header (system_clock_reference and mux_rate) */
                ld->Rdptr += 8;
                break;
            case VIDEO_ELEMENTARY_STREAM:
                code = Get_Word(ld);             /* packet_length */
                ld->Rdmax = ld->Rdptr + code;

                code = Get_Byte(ld);
                pts = 0xffffffff;
                if ((code >> 6) == 0x02)
                {
                    flags = Get_Byte(ld);
                    //ld->Rdptr++;
                    len = Get_Byte(ld);  /* parse PES_header_data_length */
                    if (flags&0x80)
                    {
                        pts = dts = mpeg_get_pts(ld, -1);
                        len -= 5;
                    }
                    if (flags&0x40)
                    {

                        dts = mpeg_get_pts(ld, -1);
                        len -= 5;
                    }
                    ld->Rdptr += len;  /* advance pointer by PES_header_data_length */
                    //printf("MPEG-2 PES packet\n");
                    goto pts_return;
                }
                else if (code == 0xff)
                {
                    /* parse MPEG-1 packet header */
                    while ((code = Get_Byte(ld)) == 0xFF);
                }

                /* stuffing bytes */
                if (code >= 0x40)
                {
                    if (code >= 0x80)
                    {
                        Fault_Flag = 1;
                    }
                    /* skip STD_buffer_scale */
                    ld->Rdptr++;
                    code = Get_Byte(ld);
                }

                if (code >= 0x30)
                {
                    if (code >= 0x40)
                    {
                        Fault_Flag = 1;
                    }
                    /* skip presentation and decoding time stamps */
                    pts = dts = mpeg_get_pts(ld, code);
                    if (code&0x10)
                    {
                        dts = mpeg_get_pts(ld, -1);
                    }
                }
                else if (code >= 0x20)
                {
                    /* skip presentation time stamps */
                    pts = dts = mpeg_get_pts(ld, code);
                    //ld->Rdptr += 4;
                }
                else if (code != 0x0f)
                {
                    Fault_Flag = 1;
                }

pts_return:
                if (pts != 0xffffffff)
                {
                    if (pts_dts_orig_flag == 0)
                    {
                        pts_dts_orig_flag = 1;
                        //pts_orig = pts;
                        mpeg.startTime = pts / 90;
                        //dts_orig = dts;
                    }
                    //mpeg.curTime = (pts-pts_orig)/90;
                    if (((pts / 90) > mpeg.curTime) || (!mpeg.curTime))
                        mpeg.curTime = pts / 90;
                }
                return;
            case ISO_END_CODE: /* end */
                /* simulate a buffer full of sequence end codes */
                l = 0;
                while (l < 2048)
                {
                    ld->Rdbfr[l++] = SEQUENCE_END_CODE >> 24;
                    ld->Rdbfr[l++] = SEQUENCE_END_CODE >> 16;
                    ld->Rdbfr[l++] = SEQUENCE_END_CODE >> 8;
                    ld->Rdbfr[l++] = SEQUENCE_END_CODE & 0xff;
                }
                ld->Rdptr = ld->Rdbfr;
                ld->Rdmax = ld->Rdbfr + 2048;
                return;
            default:
                if ((code >= SYSTEM_START_CODE) && (code <= AUDIO_ELEMENTARY_STREAM))
                {
                    /* skip system headers and non-video packets*/
                    code = Get_Word(ld);
                    ld->Rdptr += code;
                    if (ld->Rdptr > (ld->Rdbfr + 2048))
                    {
                        fseek(ld->Infile, ld->Rdptr - (ld->Rdbfr + 2048), SEEK_CUR);
                        ld->Rdptr = (ld->Rdbfr + 2048);
                    }
                }
                /*else if(code < SYSTEM_START_CODE)
                {
                  fprintf(stderr,"Unexpected startcode %08x in system layer\n",code);
                  exit(1);
                }*/
                break;
        }
    }
}

void Next_PacketAudio()
{
    int code, len, c, flags, header_len, pes_ext, ext2_len, id_ext, skip;
    int l, cnt = 0;
    unsigned short temp;
    unsigned int dts, pts;

    while (1)
    {
        code = Get_Long(ld2);

        /* remove system layer byte stuffing */
        while ((code & 0xffffff00) != 0x100)
        {
            code = (code << 8) | Get_Byte(ld2);
            if (Fault_Flag)
                return;
        }

        if (Fault_Flag)
            return;

        if (code == PACK_START_CODE)  /* pack header */
        {
            /* skip pack header (system_clock_reference and mux_rate) */
            ld2->Rdptr += 8;
        }
        else if (code == ISO_END_CODE) /* end */
        {
            /* simulate a buffer full of sequence end codes */
            l = 0;
            while (l < 2048)
            {
                ld2->Rdbfr[l++] = SEQUENCE_END_CODE >> 24;
                ld2->Rdbfr[l++] = SEQUENCE_END_CODE >> 16;
                ld2->Rdbfr[l++] = SEQUENCE_END_CODE >> 8;
                ld2->Rdbfr[l++] = SEQUENCE_END_CODE & 0xff;
            }
            ld2->Rdptr = ld2->Rdbfr;
            ld2->Rdmax = ld2->Rdbfr + 2048;
            return;
        }
        else if ((code >= 0x1c0 && code <= 0x1df) || (code == 0x1bd) || (code == 0x1fd))
        {
            pts = 0xffffffff;
            len = Get_Word(ld2);
            ld2->Rdmax = ld2->Rdptr + len;
            for (;;)
            {
                if (len < 1) break;
                c = Get_Byte(ld2);
                len--;
                if (c != 0xff) break;
            }
            if ((c & 0xc0) == 0x40)
            {
                // buffer scale & size
                Get_Byte(ld2);
                c = Get_Byte(ld2);
                len -= 2;
            }
            if ((c & 0xe0) == 0x20)
            {
                dts = pts = mpeg_get_pts(ld2, c);
                len -= 4;
                if (c & 0x10)
                {
                    dts = mpeg_get_pts(ld2, -1);
                    len -= 5;
                }
            }
            else if ((c & 0xc0) == 0x80)
            {
                flags = Get_Byte(ld2);
                header_len = Get_Byte(ld2);
                len -= 2;
                if (header_len > len)
                    break;
                len -= header_len;
                if (flags & 0x80)
                {
                    dts = pts = mpeg_get_pts(ld2, -1);
                    header_len -= 5;
                    if (flags & 0x40)
                    {
                        dts = mpeg_get_pts(ld2, -1);
                        header_len -= 5;
                    }
                }
                if (flags & 0x3f && header_len == 0)
                {
                    flags &= 0xC0;
                    printf("Further flags set but no bytes left\n");
                }
                if (flags & 0x01)
                { // PES extension
                    pes_ext = Get_Byte(ld2);
                    header_len--;
                    if (pes_ext & 0x40)
                    { // pack header - should be zero in PS
                        break;
                    }
                    // Skip PES private data, program packet sequence counter and P-STD buffer
                    skip = (pes_ext >> 4) & 0xb;
                    skip += skip & 0x9;
                    ld2->Rdptr += skip;
                    header_len -= skip;

                    if (pes_ext & 0x01)
                    { // PES extension 2
                        ext2_len = Get_Byte(ld2);
                        header_len--;
                        if ((ext2_len & 0x7f) > 0)
                        {
                            id_ext = Get_Byte(ld2);
                            if ((id_ext & 0x80) == 0)
                                code = ((code & 0xff) << 8) | id_ext;
                            header_len--;
                        }
                    }
                }
                if (header_len < 0)
                    break;
                ld2->Rdptr += header_len;

            }
            if (pts != 0xffffffff)
            {
                mpeg.auCurTime = pts / 90;
            }

            if (code == PRIVATE_STREAM_1)
            {
                code =  Get_Byte(ld2);
                len--;
                if (code >= 0x80 && code <= 0xcf)
                {
                    // audio: skip header /
                    Get_Byte(ld2);
                    Get_Byte(ld2);
                    Get_Byte(ld2);
                    len -= 3;
                    if (code >= 0xb0 && code <= 0xbf)
                    {
                        // MLP/TrueHD audio has a 4-byte header //
                        Get_Byte(ld2);
                        len--;
                    }
                }
            }
#if 0
            if (code == 0x80) //&& code <= 0x87)
            {
                mpeg.auCodec = CODEC_AC3_DEC;
                return;
            }

            if (code == 0xc0)// && code <= 0xcf)
            {
                mpeg.auCodec = CODEC_AC3_DEC;
                return;
            }
            if (code == 0x1c0)//&& code <= 0x1df)
            {
                mpeg.auCodec = CODEC_MP2;
                return;
            }
#else
            if ((code >= 0x80 && code <= 0x87) || code == 0xc0 || code == 0x1c0)   /* audio stream */
            {
                mpeg.auCodec = code;
                if ((mpeg.auCodec & 0x78) == 0)
                    mpeg.auCodec = 0x80;
                return;
            }
            else if ((!mpeg.auCodec) && (cnt >= 2))
            {
                mpeg.auCurTime = 0;
                mpeg.auCodec = 0;
                return;
            }
            else
            {
                cnt ++;
                continue;
            }
#endif

            if (ld2->Rdmax > (ld2->Rdbfr + 2048))
            {
                fseek(ld2->Infile, ld2->Rdmax - (ld2->Rdbfr + 2048), SEEK_CUR);
                ld2->Rdptr = (ld2->Rdbfr + 2048);
            }
        }
        else if (((code >= SYSTEM_START_CODE) && (code < AUDIO_ELEMENTARY_STREAM)) || (code == VIDEO_ELEMENTARY_STREAM))
        {
            // skip system headers and non-audio packets//
            code = Get_Word(ld2);
            ld2->Rdptr += code;
            if (ld2->Rdptr > (ld2->Rdbfr + 2048))
            {
                fseek(ld2->Infile, ld2->Rdptr - (ld2->Rdbfr + 2048), SEEK_CUR);
                ld2->Rdptr = (ld2->Rdbfr + 2048);
            }
        }
        /*else if(code < SYSTEM_START_CODE){
              exit(1);
        } */

    }
}


void Flush_Buffer32(layer_data *laydat)
{
    int Incnt;

    laydat->Bfr = 0;

    Incnt = laydat->Incnt;
    Incnt -= 32;

    if (System_Stream_Flag && (laydat->Rdptr >= laydat->Rdmax - 4))
    {
        while (Incnt <= 24)
        {
            if (laydat->Rdptr >= laydat->Rdmax)
                if (laydat == ld)
                    Next_Packet(0);
                else
                    Next_PacketAudio();
            laydat->Bfr |= Get_Byte(laydat) << (24 - Incnt);
            Incnt += 8;
        }
    }
    else
    {
        while (Incnt <= 24)
        {
            if (laydat->Rdptr >= laydat->Rdbfr + 2048)
                Fill_Buffer(laydat);
            laydat->Bfr |= *laydat->Rdptr++ << (24 - Incnt);
            Incnt += 8;
        }
    }
    laydat->Incnt = Incnt;

#ifdef VERIFY
    laydat->Bitcnt += 32;
#endif /* VERIFY */
}

unsigned int Get_Bits32(layer_data *laydat)
{
    unsigned int l;

    l = Show_Bits(laydat, 32);
    Flush_Buffer32(laydat);

    return l;
}


long Get_Long(layer_data *laydat)
{
    int i;

    i = Get_Word(laydat);
    return (i << 16) | Get_Word(laydat);
}

⌨️ 快捷键说明

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