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

📄 ogg.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
    if( !b_selected )    {        /* This stream isn't currently selected so we don't need to decode it,         * but we did need to store its pcr as it might be selected later on */        return;    }    if( p_oggpacket->bytes <= 0 )        return;    if( !( p_block = block_New( p_demux, p_oggpacket->bytes ) ) ) return;    /* Normalize PTS */    if( i_pts == 0 ) i_pts = 1;    else if( i_pts == -1 && i_interpolated_pts == 0 ) i_pts = 1;    else if( i_pts == -1 ) i_pts = 0;    if( p_stream->fmt.i_cat == AUDIO_ES )        p_block->i_dts = p_block->i_pts = i_pts;    else if( p_stream->fmt.i_cat == SPU_ES )    {        p_block->i_dts = p_block->i_pts = i_pts;        p_block->i_length = 0;    }    else if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) )        p_block->i_dts = p_block->i_pts = i_pts;    else if( p_stream->fmt.i_codec == VLC_FOURCC( 'd','r','a','c' ) )    {        ogg_int64_t dts = p_oggpacket->granulepos >> 31;        ogg_int64_t delay = (p_oggpacket->granulepos >> 9) & 0x1fff;        uint64_t u_pnum = dts + delay;        p_block->i_dts = p_stream->i_pcr;        p_block->i_pts = 0;        /* NB, OggDirac granulepos values are in units of 2*picturerate */        if( -1 != p_oggpacket->granulepos )            p_block->i_pts = u_pnum * INT64_C(1000000) / p_stream->f_rate / 2;    }    else    {        p_block->i_dts = i_pts;        p_block->i_pts = 0;    }    if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) &&        p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) &&        p_stream->fmt.i_codec != VLC_FOURCC( 'f','l','a','c' ) &&        p_stream->fmt.i_codec != VLC_FOURCC( 't','a','r','k' ) &&        p_stream->fmt.i_codec != VLC_FOURCC( 't','h','e','o' ) &&        p_stream->fmt.i_codec != VLC_FOURCC( 'c','m','m','l' ) &&        p_stream->fmt.i_codec != VLC_FOURCC( 'd','r','a','c' ) &&        p_stream->fmt.i_codec != VLC_FOURCC( 'k','a','t','e' ) )    {        /* We remove the header from the packet */        i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;        i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;        if( p_stream->fmt.i_codec == VLC_FOURCC( 's','u','b','t' ))        {            /* But with subtitles we need to retrieve the duration first */            int i, lenbytes = 0;            if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )            {                for( i = 0, lenbytes = 0; i < i_header_len; i++ )                {                    lenbytes = lenbytes << 8;                    lenbytes += *(p_oggpacket->packet + i_header_len - i);                }            }            if( p_oggpacket->bytes - 1 - i_header_len > 2 ||                ( p_oggpacket->packet[i_header_len + 1] != ' ' &&                  p_oggpacket->packet[i_header_len + 1] != 0 &&                  p_oggpacket->packet[i_header_len + 1] != '\n' &&                  p_oggpacket->packet[i_header_len + 1] != '\r' ) )            {                p_block->i_length = (mtime_t)lenbytes * 1000;            }        }        i_header_len++;        if( p_block->i_buffer >= (unsigned int)i_header_len )            p_block->i_buffer -= i_header_len;        else            p_block->i_buffer = 0;    }    if( p_stream->fmt.i_codec == VLC_FOURCC( 't','a','r','k' ) )    {        /* FIXME: the biggest hack I've ever done */        msg_Warn( p_demux, "tarkin pts: %"PRId64", granule: %"PRId64,                  p_block->i_pts, p_block->i_dts );        msleep(10000);    }    memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,            p_oggpacket->bytes - i_header_len );    es_out_Send( p_demux->out, p_stream->p_es, p_block );}/**************************************************************************** * Ogg_FindLogicalStreams: Find the logical streams embedded in the physical *                         stream and fill p_ogg. ***************************************************************************** * The initial page of a logical stream is marked as a 'bos' page. * Furthermore, the Ogg specification mandates that grouped bitstreams begin * together and all of the initial pages must appear before any data pages. * * On success this function returns VLC_SUCCESS. ****************************************************************************/static int Ogg_FindLogicalStreams( demux_t *p_demux ){    demux_sys_t *p_ogg = p_demux->p_sys  ;    ogg_packet oggpacket;    ogg_page oggpage;    int i_stream;#define p_stream p_ogg->pp_stream[p_ogg->i_streams - 1]    while( Ogg_ReadPage( p_demux, &oggpage ) == VLC_SUCCESS )    {        if( ogg_page_bos( &oggpage ) )        {            /* All is wonderful in our fine fine little world.             * We found the beginning of our first logical stream. */            while( ogg_page_bos( &oggpage ) )            {                logical_stream_t **pp_sav = p_ogg->pp_stream;                p_ogg->i_streams++;                p_ogg->pp_stream =                    realloc( p_ogg->pp_stream, p_ogg->i_streams *                             sizeof(logical_stream_t *) );                if( !p_ogg->pp_stream )                {                    p_ogg->pp_stream = pp_sav;                    p_ogg->i_streams--;                    return VLC_ENOMEM;                }                p_stream = malloc( sizeof(logical_stream_t) );                if( !p_stream )                    return VLC_ENOMEM;                memset( p_stream, 0, sizeof(logical_stream_t) );                p_stream->p_headers = 0;                p_stream->secondary_header_packets = 0;                es_format_Init( &p_stream->fmt, 0, 0 );                es_format_Init( &p_stream->fmt_old, 0, 0 );                /* Setup the logical stream */                p_stream->i_serial_no = ogg_page_serialno( &oggpage );                ogg_stream_init( &p_stream->os, p_stream->i_serial_no );                /* Extract the initial header from the first page and verify                 * the codec type of tis Ogg bitstream */                if( ogg_stream_pagein( &p_stream->os, &oggpage ) < 0 )                {                    /* error. stream version mismatch perhaps */                    msg_Err( p_demux, "error reading first page of "                             "Ogg bitstream data" );                    return VLC_EGENERIC;                }                /* FIXME: check return value */                ogg_stream_packetpeek( &p_stream->os, &oggpacket );                /* Check for Vorbis header */                if( oggpacket.bytes >= 7 &&                    ! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )                {                    Ogg_ReadVorbisHeader( p_stream, &oggpacket );                    msg_Dbg( p_demux, "found vorbis header" );                }                /* Check for Speex header */                else if( oggpacket.bytes >= 5 &&                    ! memcmp( oggpacket.packet, "Speex", 5 ) )                {                    Ogg_ReadSpeexHeader( p_stream, &oggpacket );                    msg_Dbg( p_demux, "found speex header, channels: %i, "                             "rate: %i,  bitrate: %i",                             p_stream->fmt.audio.i_channels,                             (int)p_stream->f_rate, p_stream->fmt.i_bitrate );                }                /* Check for Flac header (< version 1.1.1) */                else if( oggpacket.bytes >= 4 &&                    ! memcmp( oggpacket.packet, "fLaC", 4 ) )                {                    msg_Dbg( p_demux, "found FLAC header" );                    /* Grrrr!!!! Did they really have to put all the                     * important info in the second header packet!!!                     * (STREAMINFO metadata is in the following packet) */                    p_stream->b_force_backup = 1;                    p_stream->fmt.i_cat = AUDIO_ES;                    p_stream->fmt.i_codec = VLC_FOURCC( 'f','l','a','c' );                }                /* Check for Flac header (>= version 1.1.1) */                else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&                    ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&                    ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )                {                    int i_packets = ((int)oggpacket.packet[7]) << 8 |                        oggpacket.packet[8];                    msg_Dbg( p_demux, "found FLAC header version %i.%i "                             "(%i header packets)",                             oggpacket.packet[5], oggpacket.packet[6],                             i_packets );                    p_stream->b_force_backup = 1;                    p_stream->fmt.i_cat = AUDIO_ES;                    p_stream->fmt.i_codec = VLC_FOURCC( 'f','l','a','c' );                    oggpacket.packet += 13; oggpacket.bytes -= 13;                    Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket );                }                /* Check for Theora header */                else if( oggpacket.bytes >= 7 &&                         ! memcmp( oggpacket.packet, "\x80theora", 7 ) )                {                    Ogg_ReadTheoraHeader( p_stream, &oggpacket );                    msg_Dbg( p_demux,                             "found theora header, bitrate: %i, rate: %f",                             p_stream->fmt.i_bitrate, p_stream->f_rate );                }                /* Check for Dirac header */                else if( oggpacket.bytes >= 5 &&                         ! memcmp( oggpacket.packet, "BBCD\x00", 5 ) )                {                    Ogg_ReadDiracHeader( p_stream, &oggpacket );                    msg_Dbg( p_demux, "found dirac header" );                }                /* Check for Tarkin header */                else if( oggpacket.bytes >= 7 &&                         ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )                {                    oggpack_buffer opb;                    msg_Dbg( p_demux, "found tarkin header" );                    p_stream->fmt.i_cat = VIDEO_ES;                    p_stream->fmt.i_codec = VLC_FOURCC( 't','a','r','k' );                    /* Cheat and get additionnal info ;) */                    oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);                    oggpack_adv( &opb, 88 );                    oggpack_adv( &opb, 104 );                    p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );                    p_stream->f_rate = 2; /* FIXME */                    msg_Dbg( p_demux,                             "found tarkin header, bitrate: %i, rate: %f",                             p_stream->fmt.i_bitrate, p_stream->f_rate );                }                /* Check for Annodex header */                else if( oggpacket.bytes >= 7 &&                         ! memcmp( oggpacket.packet, "Annodex", 7 ) )                {                    Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,                                           &oggpacket );                    /* kill annodex track */                    free( p_stream );                    p_ogg->i_streams--;                }                /* Check for Annodex header */                else if( oggpacket.bytes >= 7 &&                         ! memcmp( oggpacket.packet, "AnxData", 7 ) )                {                    Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,                                           &oggpacket );                }                /* Check for Kate header */                else if( oggpacket.bytes >= 8 &&                    ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )                {                    Ogg_ReadKateHeader( p_stream, &oggpacket );                    msg_Dbg( p_demux, "found kate header" );                }                else if( oggpacket.bytes >= 142 &&                         !memcmp( &oggpacket.packet[1],                                   "Direct Show Samples embedded in Ogg", 35 ))                {                    /* Old header type */                    /* Check for video header (old format) */                    if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&                        oggpacket.bytes >= 184 )                    {                        p_stream->fmt.i_cat = VIDEO_ES;                        p_stream->fmt.i_codec =                            VLC_FOURCC( oggpacket.packet[68],                                        oggpacket.packet[69],                                        oggpacket.packet[70],                                        oggpacket.packet[71] );                        msg_Dbg( p_demux, "found video header of type: %.4s",                                 (char *)&p_stream->fmt.i_codec );                        p_stream->fmt.video.i_frame_rate = 10000000;                        p_stream->fmt.video.i_frame_rate_base =                            GetQWLE((oggpacket.packet+164));                        p_stream->f_rate = 10000000.0 /                            GetQWLE((oggpacket.packet+164));                        p_stream->fmt.video.i_bits_per_pixel =                            GetWLE((oggpacket.packet+182));                        if( !p_stream->fmt.video.i_bits_per_pixel )                            /* hack, FIXME */                            p_stream->fmt.video.i_bits_per_pixel = 24;                        p_stream->fmt.video.i_width =                            GetDWLE((oggpacket.packet+176));                        p_stream->fmt.video.i_height =                            GetDWLE((oggpacket.packet+180));                        msg_Dbg( p_demux,                                 "fps: %f, width:%i; height:%i, bitcount:%i",                                 p_stream->f_rate,                                 p_stream->fmt.video.i_width,                                 p_stream->fmt.video.i_height,                                 p_stream->fmt.video.i_bits_per_pixel);                    }                    /* Check for audio header (old format) */                    else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )                    {                        unsigned int i_extra_size;                        unsigned int i_format_tag;                        p_stream->fmt.i_cat = AUDIO_ES;                        i_extra_size = GetWLE((oggpacket.packet+140));                        if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )                        {                            p_stream->fmt.i_extra = i_extra_size;                            p_stream->fmt.p_extra = malloc( i_extra_size );                            if( p_stream->fmt.p_extra )                                memcpy( p_stream->fmt.p_extra,                                        oggpacket.packet + 142, i_extra_size );                            else                                p_stream->fmt.i_extra = 0;                        }                        i_format_tag = GetWLE((oggpacket.packet+124));                        p_stream->fmt.audio.i_channels =                            GetWLE((oggpacket.packet+126));                        p_stream->f_rate = p_stream->fmt.audio.i_rate =                            GetDWLE((oggpacket.packet+128));

⌨️ 快捷键说明

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