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

📄 es_out.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
                    return;            }        }        else if( i_cat == SPU_ES )        {            int idx1 = LanguageArrayIndex( p_sys->ppsz_sub_language,                                     es->psz_language_code );            if( p_sys->p_es_sub &&                p_sys->p_es_sub->fmt.i_priority >= es->fmt.i_priority )            {                int idx2 = LanguageArrayIndex( p_sys->ppsz_sub_language,                                         p_sys->p_es_sub->psz_language_code );                msg_Dbg( p_sys->p_input, "idx1=%d(%s) idx2=%d(%s)",                        idx1, es->psz_language_code, idx2,                        p_sys->p_es_sub->psz_language_code );                if( idx1 < 0 || ( idx2 >= 0 && idx2 <= idx1 ) )                    return;                /* We found a SPU that matches our language request */                i_wanted  = es->i_channel;            }            else if( idx1 >= 0 )            {                msg_Dbg( p_sys->p_input, "idx1=%d(%s)",                        idx1, es->psz_language_code );                i_wanted  = es->i_channel;            }            else if( p_sys->i_default_sub_id >= 0 )            {                if( es->i_id == p_sys->i_default_sub_id )                    i_wanted = es->i_channel;            }            if( p_sys->i_sub_last >= 0 )                i_wanted  = p_sys->i_sub_last;            if( p_sys->i_sub_id >= 0 )            {                if( es->i_id == p_sys->i_sub_id )                    i_wanted = es->i_channel;                else                    return;            }        }        else if( i_cat == VIDEO_ES )        {            i_wanted  = es->i_channel;        }        if( i_wanted == es->i_channel && !EsIsSelected( es ) )            EsSelect( out, es );    }    /* FIXME TODO handle priority here */    if( EsIsSelected( es ) )    {        if( i_cat == AUDIO_ES )        {            if( p_sys->i_mode == ES_OUT_MODE_AUTO &&                p_sys->p_es_audio &&                p_sys->p_es_audio != es &&                EsIsSelected( p_sys->p_es_audio ) )            {                EsUnselect( out, p_sys->p_es_audio, false );            }            p_sys->p_es_audio = es;        }        else if( i_cat == SPU_ES )        {            if( p_sys->i_mode == ES_OUT_MODE_AUTO &&                p_sys->p_es_sub &&                p_sys->p_es_sub != es &&                EsIsSelected( p_sys->p_es_sub ) )            {                EsUnselect( out, p_sys->p_es_sub, false );            }            p_sys->p_es_sub = es;        }        else if( i_cat == VIDEO_ES )        {            p_sys->p_es_video = es;        }    }}/** * Send a block for the given es_out * * \param out the es_out to send from * \param es the es_out_id * \param p_block the data block to send */static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block ){    es_out_sys_t *p_sys = out->p_sys;    input_thread_t    *p_input = p_sys->p_input;    es_out_pgrm_t *p_pgrm = es->p_pgrm;    int64_t i_delay;    int i_total=0;    if( es->fmt.i_cat == AUDIO_ES )        i_delay = p_sys->i_audio_delay;    else if( es->fmt.i_cat == SPU_ES )        i_delay = p_sys->i_spu_delay;    else        i_delay = 0;    if( libvlc_stats (p_input) )    {        vlc_mutex_lock( &p_input->p->counters.counters_lock );        stats_UpdateInteger( p_input, p_input->p->counters.p_demux_read,                             p_block->i_buffer, &i_total );        stats_UpdateFloat( p_input , p_input->p->counters.p_demux_bitrate,                           (float)i_total, NULL );        vlc_mutex_unlock( &p_input->p->counters.counters_lock );    }    /* Mark preroll blocks */    if( es->i_preroll_end >= 0 )    {        int64_t i_date = p_block->i_pts;        if( i_date <= 0 )            i_date = p_block->i_dts;        if( i_date < es->i_preroll_end )            p_block->i_flags |= BLOCK_FLAG_PREROLL;        else            es->i_preroll_end = -1;    }    if( p_block->i_dts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) )    {        p_block->i_dts += i_delay;    }    else if( p_block->i_dts > 0 )    {        p_block->i_dts =            input_ClockGetTS( p_input, &p_pgrm->clock, p_block->i_dts ) + i_delay;    }    if( p_block->i_pts > 0 && (p_block->i_flags&BLOCK_FLAG_PREROLL) )    {        p_block->i_pts += i_delay;    }    else if( p_block->i_pts > 0 )    {        p_block->i_pts =            input_ClockGetTS( p_input, &p_pgrm->clock, p_block->i_pts ) + i_delay;    }    if ( p_block->i_rate == INPUT_RATE_DEFAULT &&         es->fmt.i_codec == VLC_FOURCC( 't', 'e', 'l', 'x' ) )    {        mtime_t current_date = mdate();        if( !p_block->i_pts               || p_block->i_pts > current_date + 10000000               || current_date > p_block->i_pts )        {            /* ETSI EN 300 472 Annex A : do not take into account the PTS             * for teletext streams. */            p_block->i_pts = current_date + 400000                               + p_input->i_pts_delay + i_delay;        }    }    p_block->i_rate = p_sys->i_rate;    /* TODO handle mute */    if( es->p_dec &&        ( es->fmt.i_cat != AUDIO_ES ||          ( p_sys->i_rate >= INPUT_RATE_DEFAULT/AOUT_MAX_INPUT_RATE &&            p_sys->i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE ) ) )    {        bool pb_cc[4];        bool b_cc_new = false;        int i;        input_DecoderDecode( es->p_dec, p_block );        /* Check CC status */        input_DecoderIsCcPresent( es->p_dec, pb_cc );        for( i = 0; i < 4; i++ )        {            static const vlc_fourcc_t fcc[4] = {                VLC_FOURCC('c', 'c', '1', ' '),                VLC_FOURCC('c', 'c', '2', ' '),                VLC_FOURCC('c', 'c', '3', ' '),                VLC_FOURCC('c', 'c', '4', ' '),            };            static const char ppsz_description[4][18] = {                N_("Closed captions 1"),                N_("Closed captions 2"),                N_("Closed captions 3"),                N_("Closed captions 4"),            };            es_format_t fmt;            if(  es->pb_cc_present[i] || !pb_cc[i] )                continue;            msg_Dbg( p_input, "Adding CC track %d for es[%d]", 1+i, es->i_id );            es_format_Init( &fmt, SPU_ES, fcc[i] );            fmt.i_group = es->fmt.i_group;            fmt.psz_description = strdup( _(ppsz_description[i] ) );            es->pp_cc_es[i] = EsOutAdd( out, &fmt );            es->pp_cc_es[i]->p_master = es;            es_format_Clean( &fmt );            /* */            es->pb_cc_present[i] = true;            b_cc_new = true;        }        if( b_cc_new )            var_SetBool( p_sys->p_input, "intf-change", true );    }    else    {        block_Release( p_block );    }    return VLC_SUCCESS;}/***************************************************************************** * EsOutDel: *****************************************************************************/static void EsOutDel( es_out_t *out, es_out_id_t *es ){    es_out_sys_t *p_sys = out->p_sys;    bool b_reselect = false;    int i;    /* We don't try to reselect */    if( es->p_dec )    {        while( !out->p_sys->p_input->b_die && es->p_dec )        {            if( input_DecoderEmpty( es->p_dec ) )                break;            msleep( 20*1000 );        }        EsUnselect( out, es, es->p_pgrm == p_sys->p_pgrm );    }    if( es->p_pgrm == p_sys->p_pgrm )        EsOutESVarUpdate( out, es, true );    TAB_REMOVE( p_sys->i_es, p_sys->es, es );    es->p_pgrm->i_es--;    if( es->p_pgrm->i_es == 0 )    {        msg_Dbg( p_sys->p_input, "Program doesn't contain anymore ES" );    }    if( p_sys->p_es_audio == es || p_sys->p_es_video == es ||        p_sys->p_es_sub == es ) b_reselect = true;    if( p_sys->p_es_audio == es ) p_sys->p_es_audio = NULL;    if( p_sys->p_es_video == es ) p_sys->p_es_video = NULL;    if( p_sys->p_es_sub   == es ) p_sys->p_es_sub   = NULL;    switch( es->fmt.i_cat )    {        case AUDIO_ES:            p_sys->i_audio--;            break;        case SPU_ES:            p_sys->i_sub--;            break;        case VIDEO_ES:            p_sys->i_video--;            break;    }    /* Re-select another track when needed */    if( b_reselect )        for( i = 0; i < p_sys->i_es; i++ )        {            if( es->fmt.i_cat == p_sys->es[i]->fmt.i_cat )                EsOutSelect( out, p_sys->es[i], false );        }    free( es->psz_language );    free( es->psz_language_code );    es_format_Clean( &es->fmt );    free( es );}/** * Control query handler * * \param out the es_out to control * \param i_query A es_out query as defined in include/ninput.h * \param args a variable list of arguments for the query * \return VLC_SUCCESS or an error code */static int EsOutControl( es_out_t *out, int i_query, va_list args ){    es_out_sys_t *p_sys = out->p_sys;    bool  b, *pb;    int         i, *pi;    es_out_id_t *es;    switch( i_query )    {        case ES_OUT_SET_ES_STATE:            es = (es_out_id_t*) va_arg( args, es_out_id_t * );            b = (bool) va_arg( args, int );            if( b && !EsIsSelected( es ) )            {                EsSelect( out, es );                return EsIsSelected( es ) ? VLC_SUCCESS : VLC_EGENERIC;            }            else if( !b && EsIsSelected( es ) )            {                EsUnselect( out, es, es->p_pgrm == p_sys->p_pgrm );                return VLC_SUCCESS;            }            return VLC_SUCCESS;        case ES_OUT_GET_ES_STATE:            es = (es_out_id_t*) va_arg( args, es_out_id_t * );            pb = (bool*) va_arg( args, bool * );            *pb = EsIsSelected( es );            return VLC_SUCCESS;        case ES_OUT_SET_ACTIVE:        {            b = (bool) va_arg( args, int );            p_sys->b_active = b;            /* Needed ? */            if( b )                var_SetBool( p_sys->p_input, "intf-change", true );            return VLC_SUCCESS;        }        case ES_OUT_GET_ACTIVE:            pb = (bool*) va_arg( args, bool * );            *pb = p_sys->b_active;            return VLC_SUCCESS;        case ES_OUT_SET_MODE:            i = (int) va_arg( args, int );            if( i == ES_OUT_MODE_NONE || i == ES_OUT_MODE_ALL ||                i == ES_OUT_MODE_AUTO || i == ES_OUT_MODE_PARTIAL )            {                p_sys->i_mode = i;                /* Reapply policy mode */                for( i = 0; i < p_sys->i_es; i++ )                {                    if( EsIsSelected( p_sys->es[i] ) )                    {                        EsUnselect( out, p_sys->es[i],                                    p_sys->es[i]->p_pgrm == p_sys->p_pgrm );                    }                }                for( i = 0; i < p_sys->i_es; i++ )                {                    EsOutSelect( out, p_sys->es[i], false );                }                return VLC_SUCCESS;            }            return VLC_EGENERIC;        case ES_OUT_GET_MODE:            pi = (int*) va_arg( args, int* );            *pi = p_sys->i_mode;            return VLC_SUCCESS;        case ES_OUT_SET_ES:            es = (es_out_id_t*) va_arg( args, es_out_id_t * );            /* Special case NULL, NULL+i_cat */            if( es == NULL )            {                for( i = 0; i < p_sys->i_es; i++ )                {                    if( EsIsSelected( p_sys->es[i] ) )                        EsUnselect( out, p_sys->es[i],                                    p_sys->es[i]->p_pgrm == p_sys->p_pgrm );                }            }            else if( es == (es_out_id_t*)((uint8_t*)NULL+AUDIO_ES) )            {                for( i = 0; i < p_sys->i_es; i++ )                {                    if( p_sys->es[i]->fmt.i_cat == AUDIO_ES &&                        EsIsSelected( p_sys->es[i] ) )                        EsUnselect( out, p_sys->es[i],                                    p_sys->es[i]->p_pgrm == p_sys->p_pgrm );                }            }            else if( es == (es_out_id_t*)((uint8_t*)NULL+VIDEO_ES) )            {                for( i = 0; i < p_sys->i_es; i++ )                {                    if( p_sys->es[i]->fmt.i_cat == VIDEO_ES &&                        EsIsSelected( p_sys->es[i] ) )                        EsUnselect( out, p_sys->es[i],                                    p_sys->es[i]->p_pgrm == p_sys->p_pgrm );                }            }            else if( es == (es_out_id_t*)((uint8_t*)NULL+SPU_ES) )            {                for( i = 0; i < p_sys->i_es; i++ )                {                    if( p_sys->es[i]->fmt.i_cat == SPU_ES &&                        EsIsSelected( p_sys->es[i] ) )                        EsUnselect( out, p_sys->es[i],                                    p_sys->es[i]->p_pgrm == p_sys->p_pgrm );                }            }            else            {                for( i = 0; i < p_sys->i_es; i++ )                {                    if( es == p_sys->es[i] )                    {                        EsOutSelect( out, es, true );                        break;                    }

⌨️ 快捷键说明

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