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

📄 ogg.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
                        p_stream->fmt.i_bitrate =                            GetDWLE((oggpacket.packet+132)) * 8;                        p_stream->fmt.audio.i_blockalign =                            GetWLE((oggpacket.packet+136));                        p_stream->fmt.audio.i_bitspersample =                            GetWLE((oggpacket.packet+138));                        wf_tag_to_fourcc( i_format_tag,                                          &p_stream->fmt.i_codec, 0 );                        if( p_stream->fmt.i_codec ==                            VLC_FOURCC('u','n','d','f') )                        {                            p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',                                ( i_format_tag >> 8 ) & 0xff,                                i_format_tag & 0xff );                        }                        msg_Dbg( p_demux, "found audio header of type: %.4s",                                 (char *)&p_stream->fmt.i_codec );                        msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "                                 "%dbits/sample %dkb/s",                                 i_format_tag,                                 p_stream->fmt.audio.i_channels,                                 p_stream->fmt.audio.i_rate,                                 p_stream->fmt.audio.i_bitspersample,                                 p_stream->fmt.i_bitrate / 1024 );                    }                    else                    {                        msg_Dbg( p_demux, "stream %d has an old header "                            "but is of an unknown type", p_ogg->i_streams-1 );                        free( p_stream );                        p_ogg->i_streams--;                    }                }                else if( (*oggpacket.packet & PACKET_TYPE_BITS )                         == PACKET_TYPE_HEADER &&                         oggpacket.bytes >= (int)sizeof(stream_header)+1 )                {                    stream_header *st = (stream_header *)(oggpacket.packet+1);                    /* Check for video header (new format) */                    if( !strncmp( st->streamtype, "video", 5 ) )                    {                        p_stream->fmt.i_cat = VIDEO_ES;                        /* We need to get rid of the header packet */                        ogg_stream_packetout( &p_stream->os, &oggpacket );                        p_stream->fmt.i_codec =                            VLC_FOURCC( st->subtype[0], st->subtype[1],                                        st->subtype[2], st->subtype[3] );                        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(&st->time_unit);                        p_stream->f_rate = 10000000.0 /                            GetQWLE(&st->time_unit);                        p_stream->fmt.video.i_bits_per_pixel =                            GetWLE(&st->bits_per_sample);                        p_stream->fmt.video.i_width =                            GetDWLE(&st->sh.video.width);                        p_stream->fmt.video.i_height =                            GetDWLE(&st->sh.video.height);                        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 (new format) */                    else if( !strncmp( st->streamtype, "audio", 5 ) )                    {                        char p_buffer[5];                        int i_format_tag;                        p_stream->fmt.i_cat = AUDIO_ES;                        /* We need to get rid of the header packet */                        ogg_stream_packetout( &p_stream->os, &oggpacket );                        p_stream->fmt.i_extra = GetQWLE(&st->size) - sizeof(stream_header);                        if( p_stream->fmt.i_extra > 0 &&                            p_stream->fmt.i_extra < oggpacket.bytes - 1 - sizeof(stream_header) )                        {                            p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );                            if( p_stream->fmt.p_extra )                                memcpy( p_stream->fmt.p_extra, st + 1,                                        p_stream->fmt.i_extra );                            else                                p_stream->fmt.i_extra = 0;                        }                        memcpy( p_buffer, st->subtype, 4 );                        p_buffer[4] = '\0';                        i_format_tag = strtol(p_buffer,NULL,16);                        p_stream->fmt.audio.i_channels =                            GetWLE(&st->sh.audio.channels);                        p_stream->f_rate = p_stream->fmt.audio.i_rate =                            GetQWLE(&st->samples_per_unit);                        p_stream->fmt.i_bitrate =                            GetDWLE(&st->sh.audio.avgbytespersec) * 8;                        p_stream->fmt.audio.i_blockalign =                            GetWLE(&st->sh.audio.blockalign);                        p_stream->fmt.audio.i_bitspersample =                            GetWLE(&st->bits_per_sample);                        wf_tag_to_fourcc( i_format_tag,                                          &p_stream->fmt.i_codec, 0 );                        if( p_stream->fmt.i_codec ==                            VLC_FOURCC('u','n','d','f') )                        {                            p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',                                ( i_format_tag >> 8 ) & 0xff,                                i_format_tag & 0xff );                        }                        msg_Dbg( p_demux, "found audio header of type: %.4s",                                 (char *)&p_stream->fmt.i_codec );                        msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "                                 "%dbits/sample %dkb/s",                                 i_format_tag,                                 p_stream->fmt.audio.i_channels,                                 p_stream->fmt.audio.i_rate,                                 p_stream->fmt.audio.i_bitspersample,                                 p_stream->fmt.i_bitrate / 1024 );                    }                    /* Check for text (subtitles) header */                    else if( !strncmp(st->streamtype, "text", 4) )                    {                        /* We need to get rid of the header packet */                        ogg_stream_packetout( &p_stream->os, &oggpacket );                        msg_Dbg( p_demux, "found text subtitles header" );                        p_stream->fmt.i_cat = SPU_ES;                        p_stream->fmt.i_codec = VLC_FOURCC('s','u','b','t');                        p_stream->f_rate = 1000; /* granulepos is in milisec */                    }                    else                    {                        msg_Dbg( p_demux, "stream %d has a header marker "                            "but is of an unknown type", p_ogg->i_streams-1 );                        free( p_stream );                        p_ogg->i_streams--;                    }                }                else if( oggpacket.bytes >= 7 &&                             ! memcmp( oggpacket.packet, "fishead", 7 ) )                {                    /* Skeleton */                    msg_Dbg( p_demux, "stream %d is a skeleton",                                p_ogg->i_streams-1 );                    /* FIXME: https://trac.videolan.org/vlc/ticket/1412 */                }                else                {                    msg_Dbg( p_demux, "stream %d is of unknown type",                             p_ogg->i_streams-1 );                    free( p_stream );                    p_ogg->i_streams--;                }                if( Ogg_ReadPage( p_demux, &oggpage ) != VLC_SUCCESS )                    return VLC_EGENERIC;            }            /* This is the first data page, which means we are now finished             * with the initial pages. We just need to store it in the relevant             * bitstream. */            for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )            {                if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,                                       &oggpage ) == 0 )                {                    break;                }            }            return VLC_SUCCESS;        }    }#undef p_stream    return VLC_EGENERIC;}/**************************************************************************** * Ogg_BeginningOfStream: Look for Beginning of Stream ogg pages and add *                        Elementary streams. ****************************************************************************/static int Ogg_BeginningOfStream( demux_t *p_demux ){    demux_sys_t *p_ogg = p_demux->p_sys  ;    logical_stream_t *p_old_stream = p_ogg->p_old_stream;    int i_stream;    /* Find the logical streams embedded in the physical stream and     * initialize our p_ogg structure. */    if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )    {        msg_Warn( p_demux, "couldn't find any ogg logical stream" );        return VLC_EGENERIC;    }    p_ogg->i_bitrate = 0;    for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )    {        logical_stream_t *p_stream = p_ogg->pp_stream[i_stream];        p_stream->p_es = NULL;        /* Try first to reuse an old ES */        if( p_old_stream &&            p_old_stream->fmt.i_cat == p_stream->fmt.i_cat &&            p_old_stream->fmt.i_codec == p_stream->fmt.i_codec )        {            msg_Dbg( p_demux, "will reuse old stream to avoid glitch" );            p_stream->p_es = p_old_stream->p_es;            es_format_Copy( &p_stream->fmt_old, &p_old_stream->fmt );            p_old_stream->p_es = NULL;            p_old_stream = NULL;        }        if( !p_stream->p_es )            p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );        // TODO: something to do here ?        if( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )        {            /* Set the CMML stream active */            es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );        }        p_ogg->i_bitrate += p_stream->fmt.i_bitrate;        p_stream->i_pcr = p_stream->i_previous_pcr =            p_stream->i_interpolated_pcr = -1;        p_stream->b_reinit = 0;    }    if( p_ogg->p_old_stream )    {        if( p_ogg->p_old_stream->p_es )            msg_Dbg( p_demux, "old stream not reused" );        Ogg_LogicalStreamDelete( p_demux, p_ogg->p_old_stream );        p_ogg->p_old_stream = NULL;    }    return VLC_SUCCESS;}/**************************************************************************** * Ogg_EndOfStream: clean up the ES when an End of Stream is detected. ****************************************************************************/static void Ogg_EndOfStream( demux_t *p_demux ){    demux_sys_t *p_ogg = p_demux->p_sys  ;    int i_stream;    for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )        Ogg_LogicalStreamDelete( p_demux, p_ogg->pp_stream[i_stream] );    free( p_ogg->pp_stream );    /* Reinit p_ogg */    p_ogg->i_bitrate = 0;    p_ogg->i_streams = 0;    p_ogg->pp_stream = NULL;}/** * This function delete and release all data associated to a logical_stream_t */static void Ogg_LogicalStreamDelete( demux_t *p_demux, logical_stream_t *p_stream ){    if( p_stream->p_es )        es_out_Del( p_demux->out, p_stream->p_es );    ogg_stream_clear( &p_stream->os );    free( p_stream->p_headers );    es_format_Clean( &p_stream->fmt_old );    es_format_Clean( &p_stream->fmt );    free( p_stream );}/** * This function check if a we need to reset a decoder in case we are * reusing an old ES */static bool Ogg_IsVorbisFormatCompatible( const es_format_t *p_new, const es_format_t *p_old ){    int i_new = 0;    int i_old = 0;    int i;    for( i = 0; i < 3; i++ )    {        const uint8_t *p_new_extra = ( const uint8_t*)p_new->p_extra + i_new;        const uint8_t *p_old_extra = ( const uint8_t*)p_old->p_extra + i_old;        if( p_new->i_extra < i_new+2 || p_old->i_extra < i_old+2 )            return false;        const int i_new_size = GetWBE( &p_new_extra[0] );        const int i_old_size = GetWBE( &p_old_extra[0] );        if( i != 1 ) /* Ignore vorbis comment */        {            if( i_new_size != i_old_size )                return false;            if( memcmp( &p_new_extra[2], &p_old_extra[2], i_new_size ) )                return false;        }        i_new += 2 + i_new_size;        i_old += 2 + i_old_size;    }    return true;}static bool Ogg_LogicalStreamResetEsFormat( demux_t *p_demux, logical_stream_t *p_stream ){    bool b_compatible;    if( !p_stream->fmt_old.i_cat || !p_stream->fmt_old.i_codec )        return true;    /* Only vorbis is supported */    if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) )        b_compatible = Ogg_IsVorbisFormatCompatible( &p_stream->fmt, &p_stream->fmt_old );    if( !b_compatible )        msg_Warn( p_demux, "cannot reuse old stream, resetting the decoder" );    return !b_compatible;}static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,                                  ogg_packet *p_oggpacket ){    bs_t bitstream;

⌨️ 快捷键说明

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