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

📄 ogg.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * ogg.c : ogg stream demux module for vlc ***************************************************************************** * Copyright (C) 2001-2003 VideoLAN * $Id: ogg.c 11054 2005-05-18 10:23:37Z gbazin $ * * Authors: Gildas Bazin <gbazin@netcourrier.com> *          Andre Pang <Andre.Pang@csiro.au> (Annodex support) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <vlc/vlc.h>#include <vlc/input.h>#include <ogg/ogg.h>#include "codecs.h"#include "vlc_bits.h"/***************************************************************************** * Module descriptor *****************************************************************************/static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );vlc_module_begin();    set_description( _("Ogg stream demuxer" ) );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_DEMUX );    set_capability( "demux2", 50 );    set_callbacks( Open, Close );    add_shortcut( "ogg" );vlc_module_end();/***************************************************************************** * Definitions of structures and functions used by this plugins *****************************************************************************/typedef struct logical_stream_s{    ogg_stream_state os;                        /* logical stream of packets */    es_format_t      fmt;    es_out_id_t      *p_es;    double           f_rate;    int              i_serial_no;    /* the header of some logical streams (eg vorbis) contain essential     * data for the decoder. We back them up here in case we need to re-feed     * them to the decoder. */    int              b_force_backup;    int              i_packets_backup;    uint8_t          *p_headers;    int              i_headers;    /* program clock reference (in units of 90kHz) derived from the previous     * granulepos */    mtime_t          i_pcr;    mtime_t          i_interpolated_pcr;    mtime_t          i_previous_pcr;    /* Misc */    int b_reinit;    int i_theora_keyframe_granule_shift;    /* for Annodex logical bitstreams */    int secondary_header_packets;} logical_stream_t;struct demux_sys_t{    ogg_sync_state oy;        /* sync and verify incoming physical bitstream */    int i_streams;                           /* number of logical bitstreams */    logical_stream_t **pp_stream;  /* pointer to an array of logical streams */    /* program clock reference (in units of 90kHz) derived from the pcr of     * the sub-streams */    mtime_t i_pcr;    /* stream state */    int     i_eos;    /* bitrate */    int     i_bitrate;};/* OggDS headers for the new header format (used in ogm files) */typedef struct stream_header_video{    ogg_int32_t width;    ogg_int32_t height;} stream_header_video;typedef struct stream_header_audio{    ogg_int16_t channels;    ogg_int16_t blockalign;    ogg_int32_t avgbytespersec;} stream_header_audio;typedef struct stream_header{    char        streamtype[8];    char        subtype[4];    ogg_int32_t size;                               /* size of the structure */    ogg_int64_t time_unit;                              /* in reference time */    ogg_int64_t samples_per_unit;    ogg_int32_t default_len;                                /* in media time */    ogg_int32_t buffersize;    ogg_int16_t bits_per_sample;    union    {        /* Video specific */        stream_header_video video;        /* Audio specific */        stream_header_audio audio;    } sh;} stream_header;#define OGG_BLOCK_SIZE 4096/* Some defines from OggDS */#define PACKET_TYPE_HEADER   0x01#define PACKET_TYPE_BITS     0x07#define PACKET_LEN_BITS01    0xc0#define PACKET_LEN_BITS2     0x02#define PACKET_IS_SYNCPOINT  0x08/***************************************************************************** * Local prototypes *****************************************************************************/static int  Demux  ( demux_t * );static int  Control( demux_t *, int, va_list );/* Bitstream manipulation */static int  Ogg_ReadPage     ( demux_t *, ogg_page * );static void Ogg_UpdatePCR    ( logical_stream_t *, ogg_packet * );static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );static int Ogg_BeginningOfStream( demux_t *p_demux );static int Ogg_FindLogicalStreams( demux_t *p_demux );static void Ogg_EndOfStream( demux_t *p_demux );/* Logical bitstream headers */static void Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );static void Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );static void Ogg_ReadAnnodexHeader( vlc_object_t *, logical_stream_t *, ogg_packet * );/***************************************************************************** * Open: initializes ogg demux structures *****************************************************************************/static int Open( vlc_object_t * p_this ){    demux_t *p_demux = (demux_t *)p_this;    demux_sys_t    *p_sys;    uint8_t        *p_peek;    /* Check if we are dealing with an ogg stream */    if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;    if( strcmp( p_demux->psz_demux, "ogg" ) && strncmp( p_peek, "OggS", 4 ) )    {        return VLC_EGENERIC;    }    /* Set exported functions */    p_demux->pf_demux = Demux;    p_demux->pf_control = Control;    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );    memset( p_sys, 0, sizeof( demux_sys_t ) );    p_sys->i_bitrate = 0;    p_sys->pp_stream = NULL;    /* Begnning of stream, tell the demux to look for elementary streams. */    p_sys->i_eos = 0;    /* Initialize the Ogg physical bitstream parser */    ogg_sync_init( &p_sys->oy );    return VLC_SUCCESS;}/***************************************************************************** * Close: frees unused data *****************************************************************************/static void Close( vlc_object_t *p_this ){    demux_t *p_demux = (demux_t *)p_this;    demux_sys_t *p_sys = p_demux->p_sys  ;    /* Cleanup the bitstream parser */    ogg_sync_clear( &p_sys->oy );    Ogg_EndOfStream( p_demux );    free( p_sys );}/***************************************************************************** * Demux: reads and demuxes data packets ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, 1 otherwise *****************************************************************************/static int Demux( demux_t * p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    ogg_page    oggpage;    ogg_packet  oggpacket;    int         i_stream;    if( p_sys->i_eos == p_sys->i_streams )    {        if( p_sys->i_eos )        {            msg_Dbg( p_demux, "end of a group of logical streams" );            Ogg_EndOfStream( p_demux );        }        p_sys->i_eos = 0;        if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS ) return 0;        msg_Dbg( p_demux, "beginning of a group of logical streams" );        es_out_Control( p_demux->out, ES_OUT_RESET_PCR );    }    /*     * Demux an ogg page from the stream     */    if( Ogg_ReadPage( p_demux, &oggpage ) != VLC_SUCCESS )    {        return 0; /* EOF */    }    /* Test for End of Stream */    if( ogg_page_eos( &oggpage ) ) p_sys->i_eos++;    for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )    {        logical_stream_t *p_stream = p_sys->pp_stream[i_stream];        if( ogg_stream_pagein( &p_stream->os, &oggpage ) != 0 )            continue;        while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )        {            /* Read info from any secondary header packets, if there are any */            if( p_stream->secondary_header_packets > 0 )            {                if( p_stream->fmt.i_codec == VLC_FOURCC('t','h','e','o') &&                        oggpacket.bytes >= 7 &&                        ! strncmp( &oggpacket.packet[1], "theora", 6 ) )                {                    Ogg_ReadTheoraHeader( p_stream, &oggpacket );                    p_stream->secondary_header_packets = 0;                }                else if( p_stream->fmt.i_codec == VLC_FOURCC('v','o','r','b') &&                        oggpacket.bytes >= 7 &&                        ! strncmp( &oggpacket.packet[1], "vorbis", 6 ) )                {                    Ogg_ReadVorbisHeader( p_stream, &oggpacket );                    p_stream->secondary_header_packets = 0;                }                else if ( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )                {                    p_stream->secondary_header_packets = 0;                }            }            if( p_stream->b_reinit )            {                /* If synchro is re-initialized we need to drop all the packets                 * until we find a new dated one. */                Ogg_UpdatePCR( p_stream, &oggpacket );                if( p_stream->i_pcr >= 0 )                {                    p_stream->b_reinit = 0;                }                else                {                    p_stream->i_interpolated_pcr = -1;                    continue;                }                /* An Ogg/vorbis packet contains an end date granulepos */                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' ) )                {                    if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )                    {                        Ogg_DecodePacket( p_demux, p_stream, &oggpacket );                    }                    else                    {                        es_out_Control( p_demux->out, ES_OUT_SET_PCR,                                        p_stream->i_pcr );                    }                    continue;                }            }            Ogg_DecodePacket( p_demux, p_stream, &oggpacket );        }        break;    }    i_stream = 0; p_sys->i_pcr = -1;    for( ; i_stream < p_sys->i_streams; i_stream++ )    {        logical_stream_t *p_stream = p_sys->pp_stream[i_stream];        if( p_stream->fmt.i_cat == SPU_ES )            continue;        if( p_stream->i_interpolated_pcr < 0 )            continue;        if( p_sys->i_pcr < 0 || p_stream->i_interpolated_pcr < p_sys->i_pcr )            p_sys->i_pcr = p_stream->i_interpolated_pcr;    }    if( p_sys->i_pcr >= 0 )    {        es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );    }

⌨️ 快捷键说明

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