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

📄 es_out.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * es_out.c: Es Out handler for input. ***************************************************************************** * Copyright (C) 2003-2004 the VideoLAN team * $Id: f1b4f3810e4c05982c2a328b9cda4acec28773c3 $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl> * * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <stdio.h>#include <vlc_input.h>#include <vlc_es_out.h>#include <vlc_block.h>#include <vlc_aout.h>#include "input_internal.h"#include <vlc_iso_lang.h>/* FIXME we should find a better way than including that */#include "../text/iso-639_def.h"/***************************************************************************** * Local prototypes *****************************************************************************/typedef struct{    /* Program ID */    int i_id;    /* Number of es for this pgrm */    int i_es;    bool b_selected;    /* Clock for this program */    input_clock_t clock;    char    *psz_name;    char    *psz_now_playing;    char    *psz_publisher;    vlc_epg_t *p_epg;} es_out_pgrm_t;struct es_out_id_t{    /* ES ID */    int       i_id;    es_out_pgrm_t *p_pgrm;    /* Misc. */    int64_t i_preroll_end;    /* Channel in the track type */    int         i_channel;    es_format_t fmt;    char        *psz_language;    char        *psz_language_code;    decoder_t   *p_dec;    /* Fields for Video with CC */    bool  pb_cc_present[4];    es_out_id_t  *pp_cc_es[4];    /* Field for CC track from a master video */    es_out_id_t *p_master;};struct es_out_sys_t{    input_thread_t *p_input;    /* all programs */    int           i_pgrm;    es_out_pgrm_t **pgrm;    es_out_pgrm_t **pp_selected_pgrm; /* --programs */    es_out_pgrm_t *p_pgrm;  /* Master program */    /* all es */    int         i_id;    int         i_es;    es_out_id_t **es;    /* mode gestion */    bool  b_active;    int         i_mode;    /* es count */    int         i_audio;    int         i_video;    int         i_sub;    /* es to select */    int         i_audio_last, i_audio_id;    int         i_sub_last, i_sub_id;    int         i_default_sub_id;   /* As specified in container; if applicable */    char        **ppsz_audio_language;    char        **ppsz_sub_language;    /* current main es */    es_out_id_t *p_es_audio;    es_out_id_t *p_es_video;    es_out_id_t *p_es_sub;    /* delay */    int64_t i_audio_delay;    int64_t i_spu_delay;    /* Rate used to rescale ES ts */    int         i_rate;};static es_out_id_t *EsOutAdd    ( es_out_t *, es_format_t * );static int          EsOutSend   ( es_out_t *, es_out_id_t *, block_t * );static void         EsOutDel    ( es_out_t *, es_out_id_t * );static void         EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force );static int          EsOutControl( es_out_t *, int i_query, va_list );static void         EsOutAddInfo( es_out_t *, es_out_id_t *es );static bool EsIsSelected( es_out_id_t *es );static void EsSelect( es_out_t *out, es_out_id_t *es );static void EsUnselect( es_out_t *out, es_out_id_t *es, bool b_update );static char *LanguageGetName( const char *psz_code );static char *LanguageGetCode( const char *psz_lang );static char **LanguageSplit( const char *psz_langs );static int LanguageArrayIndex( char **ppsz_langs, char *psz_lang );static char *EsOutProgramGetMetaName( es_out_pgrm_t *p_pgrm );static const vlc_fourcc_t EsOutFourccClosedCaptions[4] = {    VLC_FOURCC('c', 'c', '1', ' '),    VLC_FOURCC('c', 'c', '2', ' '),    VLC_FOURCC('c', 'c', '3', ' '),    VLC_FOURCC('c', 'c', '4', ' '),};static inline int EsOutGetClosedCaptionsChannel( vlc_fourcc_t fcc ){    int i;    for( i = 0; i < 4; i++ )    {        if( fcc == EsOutFourccClosedCaptions[i] )            return i;    }    return -1;}/***************************************************************************** * input_EsOutNew: *****************************************************************************/es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate ){    vlc_value_t  val;    int i;    es_out_t     *out = malloc( sizeof( es_out_t ) );    if( !out ) return NULL;    es_out_sys_t *p_sys = malloc( sizeof( es_out_sys_t ) );    if( !p_sys )    {        free( out );        return NULL;    }    out->pf_add     = EsOutAdd;    out->pf_send    = EsOutSend;    out->pf_del     = EsOutDel;    out->pf_control = EsOutControl;    out->p_sys      = p_sys;    out->b_sout     = p_input->p->p_sout != NULL;    p_sys->p_input = p_input;    p_sys->b_active = false;    p_sys->i_mode   = ES_OUT_MODE_AUTO;    TAB_INIT( p_sys->i_pgrm, p_sys->pgrm );    p_sys->p_pgrm   = NULL;    p_sys->i_id    = 0;    TAB_INIT( p_sys->i_es, p_sys->es );    p_sys->i_audio = 0;    p_sys->i_video = 0;    p_sys->i_sub   = 0;    /* */    var_Get( p_input, "audio-track", &val );    p_sys->i_audio_last = val.i_int;    var_Get( p_input, "sub-track", &val );    p_sys->i_sub_last = val.i_int;    p_sys->i_default_sub_id   = -1;    if( !p_input->b_preparsing )    {        var_Get( p_input, "audio-language", &val );        p_sys->ppsz_audio_language = LanguageSplit(val.psz_string);        if( p_sys->ppsz_audio_language )        {            for( i = 0; p_sys->ppsz_audio_language[i]; i++ )                msg_Dbg( p_input, "selected audio language[%d] %s",                         i, p_sys->ppsz_audio_language[i] );        }        free( val.psz_string );        var_Get( p_input, "sub-language", &val );        p_sys->ppsz_sub_language = LanguageSplit(val.psz_string);        if( p_sys->ppsz_sub_language )        {            for( i = 0; p_sys->ppsz_sub_language[i]; i++ )                msg_Dbg( p_input, "selected subtitle language[%d] %s",                         i, p_sys->ppsz_sub_language[i] );        }        free( val.psz_string );    }    else    {        p_sys->ppsz_sub_language = NULL;        p_sys->ppsz_audio_language = NULL;    }    var_Get( p_input, "audio-track-id", &val );    p_sys->i_audio_id = val.i_int;    var_Get( p_input, "sub-track-id", &val );    p_sys->i_sub_id = val.i_int;    p_sys->p_es_audio = NULL;    p_sys->p_es_video = NULL;    p_sys->p_es_sub   = NULL;    p_sys->i_audio_delay= 0;    p_sys->i_spu_delay  = 0;    p_sys->i_rate = i_rate;    return out;}/***************************************************************************** * input_EsOutDelete: *****************************************************************************/void input_EsOutDelete( es_out_t *out ){    es_out_sys_t *p_sys = out->p_sys;    int i;    for( i = 0; i < p_sys->i_es; i++ )    {        if( p_sys->es[i]->p_dec )        {            input_DecoderDelete( p_sys->es[i]->p_dec );        }        free( p_sys->es[i]->psz_language );        free( p_sys->es[i]->psz_language_code );        es_format_Clean( &p_sys->es[i]->fmt );        free( p_sys->es[i] );    }    if( p_sys->ppsz_audio_language )    {        for( i = 0; p_sys->ppsz_audio_language[i]; i++ )            free( p_sys->ppsz_audio_language[i] );        free( p_sys->ppsz_audio_language );    }    if( p_sys->ppsz_sub_language )    {        for( i = 0; p_sys->ppsz_sub_language[i]; i++ )            free( p_sys->ppsz_sub_language[i] );        free( p_sys->ppsz_sub_language );    }    free( p_sys->es );    /* FIXME duplicate work EsOutProgramDel (but we cannot use it) add a EsOutProgramClean ? */    for( i = 0; i < p_sys->i_pgrm; i++ )    {        es_out_pgrm_t *p_pgrm = p_sys->pgrm[i];        free( p_pgrm->psz_now_playing );        free( p_pgrm->psz_publisher );        free( p_pgrm->psz_name );        if( p_pgrm->p_epg )            vlc_epg_Delete( p_pgrm->p_epg );        free( p_pgrm );    }    TAB_CLEAN( p_sys->i_pgrm, p_sys->pgrm );    free( p_sys );    free( out );}es_out_id_t *input_EsOutGetFromID( es_out_t *out, int i_id ){    int i;    if( i_id < 0 )    {        /* Special HACK, -i_id is tha cat of the stream */        return (es_out_id_t*)((uint8_t*)NULL-i_id);    }    for( i = 0; i < out->p_sys->i_es; i++ )    {        if( out->p_sys->es[i]->i_id == i_id )            return out->p_sys->es[i];    }    return NULL;}static void EsOutDiscontinuity( es_out_t *out, bool b_flush, bool b_audio ){    es_out_sys_t      *p_sys = out->p_sys;    int i;    for( i = 0; i < p_sys->i_es; i++ )    {        es_out_id_t *es = p_sys->es[i];        /* Send a dummy block to let decoder know that         * there is a discontinuity */        if( es->p_dec && ( !b_audio || es->fmt.i_cat == AUDIO_ES ) )            input_DecoderDiscontinuity( es->p_dec, b_flush );    }}void input_EsOutChangeRate( es_out_t *out, int i_rate ){    es_out_sys_t      *p_sys = out->p_sys;    int i;    p_sys->i_rate = i_rate;    EsOutDiscontinuity( out, false, false );    for( i = 0; i < p_sys->i_pgrm; i++ )        input_ClockSetRate( &p_sys->pgrm[i]->clock, i_rate );}void input_EsOutSetDelay( es_out_t *out, int i_cat, int64_t i_delay ){    es_out_sys_t *p_sys = out->p_sys;    if( i_cat == AUDIO_ES )        p_sys->i_audio_delay = i_delay;    else if( i_cat == SPU_ES )        p_sys->i_spu_delay = i_delay;}void input_EsOutChangeState( es_out_t *out ){    es_out_sys_t *p_sys = out->p_sys;    input_thread_t *p_input = p_sys->p_input;    if( p_input->i_state  == PAUSE_S )    {        /* Send discontinuity to decoders (it will allow them to flush         *                  * if implemented */        EsOutDiscontinuity( out, false, false );    }    else    {        /* Out of pause, reset pcr */        es_out_Control( out, ES_OUT_RESET_PCR );    }}void input_EsOutChangePosition( es_out_t *out ){    //es_out_sys_t *p_sys = out->p_sys;    es_out_Control( out, ES_OUT_RESET_PCR );    EsOutDiscontinuity( out, true, false );}bool input_EsOutDecodersEmpty( es_out_t *out ){    es_out_sys_t      *p_sys = out->p_sys;    int i;    for( i = 0; i < p_sys->i_es; i++ )    {        es_out_id_t *es = p_sys->es[i];        if( es->p_dec && !input_DecoderEmpty( es->p_dec ) )            return false;    }    return true;}/***************************************************************************** * *****************************************************************************/static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, es_format_t *fmt, const char *psz_language,                                     bool b_delete ){    es_out_sys_t      *p_sys = out->p_sys;    input_thread_t    *p_input = p_sys->p_input;    const  bool b_teletext = fmt->i_cat == SPU_ES && fmt->i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' );

⌨️ 快捷键说明

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