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

📄 es_out.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
    TAB_REMOVE( p_sys->i_pgrm, p_sys->pgrm, p_pgrm );    /* If program is selected we need to unselect it */    if( p_sys->p_pgrm == p_pgrm ) p_sys->p_pgrm = 0;    if( p_pgrm->psz_now_playing ) free( p_pgrm->psz_now_playing );    free( p_pgrm );    /* Update "program" variable */    val.i_int = i_group;    var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );    var_SetBool( p_sys->p_input, "intf-change", VLC_TRUE );    return VLC_SUCCESS;}/* EsOutProgramMeta: */static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta ){    es_out_sys_t      *p_sys = out->p_sys;    es_out_pgrm_t     *p_pgrm = NULL;    input_thread_t    *p_input = p_sys->p_input;    char              *psz_cat = malloc( strlen(_("Program")) + 10 );    char              *psz_name = NULL;    char              *psz_now_playing = NULL;    char              *psz_provider = NULL;    int i;    msg_Dbg( p_input, "EsOutProgramMeta: number=%d", i_group );    sprintf( psz_cat, "%s %d", _("Program"), i_group );    for( i = 0; i < p_meta->i_meta; i++ )    {        msg_Dbg( p_input, "  - %s = %s", p_meta->name[i], p_meta->value[i] );        input_Control( p_input, INPUT_ADD_INFO, psz_cat,                      _(p_meta->name[i]), "%s", p_meta->value[i] );        if( !strcasecmp( p_meta->name[i], "Name" ) )            psz_name = p_meta->value[i];        else if( !strcasecmp( p_meta->name[i], "Provider" ) )            psz_provider = p_meta->value[i];        else if( !strcasecmp( p_meta->name[i], VLC_META_NOW_PLAYING ) )            psz_now_playing = p_meta->value[i];    }    if( !psz_name && !psz_now_playing )    {        free( psz_cat );        return;    }    for( i = 0; i < p_sys->i_pgrm; i++ )    {        if( p_sys->pgrm[i]->i_id == i_group )        {            p_pgrm = p_sys->pgrm[i];            break;        }    }    if( p_pgrm == NULL )        p_pgrm = EsOutProgramAdd( out, i_group );    /* Update the description text of the program */    if( psz_name && *psz_name )    {        vlc_value_t val;        vlc_value_t text;        /* ugly but it works */        val.i_int = i_group;        var_Change( p_input, "program", VLC_VAR_DELCHOICE, &val, NULL );        if( psz_provider && *psz_provider )        {            asprintf( &text.psz_string, "%s [%s]", psz_name, psz_provider );            var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, &text );            free( text.psz_string );        }        else        {            text.psz_string = psz_name;            var_Change( p_input, "program", VLC_VAR_ADDCHOICE, &val, &text );        }    }    if( psz_now_playing )    {        p_pgrm->psz_now_playing = strdup(psz_now_playing);        if( p_sys->p_pgrm == p_pgrm )        {            input_Control( p_input, INPUT_ADD_INFO, _("Meta-information"),                           VLC_META_NOW_PLAYING, "%s", psz_now_playing );        }    }    free( psz_cat );}/* EsOutAdd: *  Add an es_out */static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt ){    es_out_sys_t      *p_sys = out->p_sys;    input_thread_t    *p_input = p_sys->p_input;    es_out_id_t       *es = malloc( sizeof( es_out_id_t ) );    es_out_pgrm_t     *p_pgrm = NULL;    int i;    if( fmt->i_group < 0 )    {        msg_Err( p_input, "invalid group number" );        return NULL;    }    /* Search the program */    for( i = 0; i < p_sys->i_pgrm; i++ )    {        if( fmt->i_group == p_sys->pgrm[i]->i_id )        {            p_pgrm = p_sys->pgrm[i];            break;        }    }    if( p_pgrm == NULL )    {        /* Create a new one */        p_pgrm = EsOutProgramAdd( out, fmt->i_group );    }    /* Increase ref count for program */    p_pgrm->i_es++;    /* Set up ES */    if( fmt->i_id < 0 )        fmt->i_id = out->p_sys->i_id;    es->i_id = fmt->i_id;    es->p_pgrm = p_pgrm;    es_format_Copy( &es->fmt, fmt );    es->i_preroll_end = -1;    switch( fmt->i_cat )    {    case AUDIO_ES:        es->i_channel = p_sys->i_audio;        break;    case VIDEO_ES:        es->i_channel = p_sys->i_video;        if( fmt->video.i_frame_rate && fmt->video.i_frame_rate_base )            vlc_reduce( &es->fmt.video.i_frame_rate,                        &es->fmt.video.i_frame_rate_base,                        fmt->video.i_frame_rate,                        fmt->video.i_frame_rate_base, 0 );        break;    case SPU_ES:        es->i_channel = p_sys->i_sub;        break;    default:        es->i_channel = 0;        break;    }    es->psz_language = LanguageGetName( fmt->psz_language ); /* remember so we only need to do it once */    es->psz_language_code = LanguageGetCode( fmt->psz_language );    es->p_dec = NULL;    if( es->p_pgrm == p_sys->p_pgrm )        EsOutESVarUpdate( out, es, VLC_FALSE );    /* Select it if needed */    EsOutSelect( out, es, VLC_FALSE );    TAB_APPEND( out->p_sys->i_es, out->p_sys->es, es );    p_sys->i_id++;  /* always incremented */    switch( 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;    }    EsOutAddInfo( out, es );    return es;}static void EsSelect( es_out_t *out, es_out_id_t *es ){    es_out_sys_t   *p_sys = out->p_sys;    input_thread_t *p_input = p_sys->p_input;    vlc_value_t    val;    char           *psz_var;    if( es->p_dec )    {        msg_Warn( p_input, "ES 0x%x is already selected", es->i_id );        return;    }    if( es->fmt.i_cat == VIDEO_ES || es->fmt.i_cat == SPU_ES )    {        if( !var_GetBool( p_input, "video" ) ||            ( p_input->p_sout && !var_GetBool( p_input, "sout-video" ) ) )        {            msg_Dbg( p_input, "video is disabled, not selecting ES 0x%x",                     es->i_id );            return;        }    }    else if( es->fmt.i_cat == AUDIO_ES )    {        var_Get( p_input, "audio", &val );        if( !var_GetBool( p_input, "audio" ) ||            ( p_input->p_sout && !var_GetBool( p_input, "sout-audio" ) ) )        {            msg_Dbg( p_input, "audio is disabled, not selecting ES 0x%x",                     es->i_id );            return;        }    }    es->i_preroll_end = -1;    es->p_dec = input_DecoderNew( p_input, &es->fmt, VLC_FALSE );    if( es->p_dec == NULL || es->p_pgrm != p_sys->p_pgrm )        return;    if( es->fmt.i_cat == VIDEO_ES )        psz_var = "video-es";    else if( es->fmt.i_cat == AUDIO_ES )        psz_var = "audio-es";    else if( es->fmt.i_cat == SPU_ES )        psz_var = "spu-es";    else        return;    /* Mark it as selected */    val.i_int = es->i_id;    var_Change( p_input, psz_var, VLC_VAR_SETVALUE, &val, NULL );    var_SetBool( p_sys->p_input, "intf-change", VLC_TRUE );}static void EsUnselect( es_out_t *out, es_out_id_t *es, vlc_bool_t b_update ){    es_out_sys_t   *p_sys = out->p_sys;    input_thread_t *p_input = p_sys->p_input;    vlc_value_t    val;    char           *psz_var;    if( es->p_dec == NULL )    {        msg_Warn( p_input, "ES 0x%x is already unselected", es->i_id );        return;    }    input_DecoderDelete( es->p_dec );    es->p_dec = NULL;    if( !b_update )        return;    /* Update var */    if( es->p_dec == NULL )        return;    if( es->fmt.i_cat == VIDEO_ES )        psz_var = "video-es";    else if( es->fmt.i_cat == AUDIO_ES )        psz_var = "audio-es";    else if( es->fmt.i_cat == SPU_ES )        psz_var = "spu-es";    else        return;    /* Mark it as selected */    val.i_int = -1;    var_Change( p_input, psz_var, VLC_VAR_SETVALUE, &val, NULL );    var_SetBool( p_sys->p_input, "intf-change", VLC_TRUE );}/** * Select an ES given the current mode * XXX: you need to take a the lock before (stream.stream_lock) * * \param out The es_out structure * \param es es_out_id structure * \param b_force ... * \return nothing */static void EsOutSelect( es_out_t *out, es_out_id_t *es, vlc_bool_t b_force ){    es_out_sys_t      *p_sys = out->p_sys;    int i_cat = es->fmt.i_cat;    if( !p_sys->b_active ||        ( !b_force && es->fmt.i_priority < 0 ) )    {        return;    }    if( p_sys->i_mode == ES_OUT_MODE_ALL || b_force )    {        if( !es->p_dec )            EsSelect( out, es );    }    else if( p_sys->i_mode == ES_OUT_MODE_PARTIAL )    {        vlc_value_t val;        int i;        var_Get( p_sys->p_input, "programs", &val );        for ( i = 0; i < val.p_list->i_count; i++ )        {            if ( val.p_list->p_values[i].i_int == es->p_pgrm->i_id || b_force )            {                if( !es->p_dec )                    EsSelect( out, es );                break;            }        }        var_Change( p_sys->p_input, "programs", VLC_VAR_FREELIST, &val, NULL );    }    else if( p_sys->i_mode == ES_OUT_MODE_AUTO )    {        int i_wanted  = -1;        if( es->p_pgrm != p_sys->p_pgrm )            return;        if( i_cat == AUDIO_ES )        {            int idx1 = LanguageArrayIndex( p_sys->ppsz_audio_language,                                     es->psz_language_code );            if( p_sys->p_es_audio &&                p_sys->p_es_audio->fmt.i_priority >= es->fmt.i_priority )            {                int idx2 = LanguageArrayIndex( p_sys->ppsz_audio_language,                                         p_sys->p_es_audio->psz_language_code );                if( idx1 < 0 || ( idx2 >= 0 && idx2 <= idx1 ) )                    return;                i_wanted = es->i_channel;            }            else            {                /* Select audio if (no audio selected yet)                 * - no audio-language                 * - no audio code for the ES                 * - audio code in the requested list */                if( idx1 >= 0 ||                    !strcmp( es->psz_language_code, "??" ) ||                    !p_sys->ppsz_audio_language )                    i_wanted = es->i_channel;            }            if( p_sys->i_audio_last >= 0 )                i_wanted = p_sys->i_audio_last;        }        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;            }            if( p_sys->i_sub_last >= 0 )                i_wanted  = p_sys->i_sub_last;        }        else if( i_cat == VIDEO_ES )        {            i_wanted  = es->i_channel;        }        if( i_wanted == es->i_channel && es->p_dec == NULL )            EsSelect( out, es );    }    /* FIXME TODO handle priority here */    if( es->p_dec )    {        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 &&                p_sys->p_es_audio->p_dec )            {                EsUnselect( out, p_sys->p_es_audio, VLC_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 &&                p_sys->p_es_sub->p_dec )            {                EsUnselect( out, p_sys->p_es_sub, VLC_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;    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;    /* 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;    }    /* +11 -> avoid null value with non null dts/pts */    if( p_block->i_dts > 0 )    {        p_block->i_dts =            input_ClockGetTS( p_input, &p_pgrm->clock,                              ( p_block->i_dts + 11 ) * 9 / 100 ) + i_delay;    }    if( p_block->i_pts > 0 )    {        p_block->i_pts =            input_ClockGetTS( p_input, &p_pgrm->clock,                              ( p_block->i_pts + 11 ) * 9 / 100 ) + i_delay;    }    if ( 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_input->i_rate;    /* TODO handle mute */    if( es->p_dec && ( es->fmt.i_cat != AUDIO_ES ||        p_input->i_rate == INPUT_RATE_DEFAULT ) )    {        input_DecoderDecode( es->p_dec, p_block );    }    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;

⌨️ 快捷键说明

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