transcode.c

来自「uclinux 下的vlc播放器源代码」· C语言 代码 · 共 1,822 行 · 第 1/5 页

C
1,822
字号
        }    }    /* Audio settings */    var_Get( p_stream, SOUT_CFG_PREFIX "audio-sync", &val );    p_sys->b_master_sync = val.b_bool;    if( p_sys->f_fps > 0 ) p_sys->b_master_sync = VLC_TRUE;    p_stream->pf_add    = Add;    p_stream->pf_del    = Del;    p_stream->pf_send   = Send;    p_stream->p_sys     = p_sys;    return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t * p_this ){    sout_stream_t       *p_stream = (sout_stream_t*)p_this;    sout_stream_sys_t   *p_sys = p_stream->p_sys;    sout_StreamDelete( p_sys->p_out );    while( p_sys->p_audio_cfg != NULL )    {        sout_cfg_t *p_next = p_sys->p_audio_cfg->p_next;        if( p_sys->p_audio_cfg->psz_name )            free( p_sys->p_audio_cfg->psz_name );        if( p_sys->p_audio_cfg->psz_value )            free( p_sys->p_audio_cfg->psz_value );        free( p_sys->p_audio_cfg );        p_sys->p_audio_cfg = p_next;    }    if( p_sys->psz_aenc ) free( p_sys->psz_aenc );    while( p_sys->p_video_cfg != NULL )    {        sout_cfg_t *p_next = p_sys->p_video_cfg->p_next;        if( p_sys->p_video_cfg->psz_name )            free( p_sys->p_video_cfg->psz_name );        if( p_sys->p_video_cfg->psz_value )            free( p_sys->p_video_cfg->psz_value );        free( p_sys->p_video_cfg );        p_sys->p_video_cfg = p_next;    }    if( p_sys->psz_venc ) free( p_sys->psz_venc );    while( p_sys->p_deinterlace_cfg != NULL )    {        sout_cfg_t *p_next = p_sys->p_deinterlace_cfg->p_next;        if( p_sys->p_deinterlace_cfg->psz_name )            free( p_sys->p_deinterlace_cfg->psz_name );        if( p_sys->p_deinterlace_cfg->psz_value )            free( p_sys->p_deinterlace_cfg->psz_value );        free( p_sys->p_deinterlace_cfg );        p_sys->p_deinterlace_cfg = p_next;    }    if( p_sys->psz_deinterlace ) free( p_sys->psz_deinterlace );    while( p_sys->p_spu_cfg != NULL )    {        sout_cfg_t *p_next = p_sys->p_spu_cfg->p_next;        if( p_sys->p_spu_cfg->psz_name )            free( p_sys->p_spu_cfg->psz_name );        if( p_sys->p_spu_cfg->psz_value )            free( p_sys->p_spu_cfg->psz_value );        free( p_sys->p_spu_cfg );        p_sys->p_spu_cfg = p_next;    }    if( p_sys->psz_senc ) free( p_sys->psz_senc );    if( p_sys->p_spu ) spu_Destroy( p_sys->p_spu );    while( p_sys->p_osd_cfg != NULL )    {        sout_cfg_t *p_next = p_sys->p_osd_cfg->p_next;        if( p_sys->p_osd_cfg->psz_name )            free( p_sys->p_osd_cfg->psz_name );        if( p_sys->p_osd_cfg->psz_value )            free( p_sys->p_osd_cfg->psz_value );        free( p_sys->p_osd_cfg );        p_sys->p_osd_cfg = p_next;    }    if( p_sys->psz_osdenc ) free( p_sys->psz_osdenc );    vlc_object_destroy( p_sys );}struct sout_stream_id_t{    vlc_fourcc_t  b_transcode;    /* id of the out stream */    void *id;    /* Decoder */    decoder_t       *p_decoder;    /* Filters */    filter_t        *pp_filter[10];    int             i_filter;    filter_t        *pp_vfilter[10];    int             i_vfilter;    /* Encoder */    encoder_t       *p_encoder;    /* Sync */    date_t          interpolated_pts;};static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt ){    sout_stream_sys_t *p_sys = p_stream->p_sys;    sout_stream_id_t *id;    id = malloc( sizeof( sout_stream_id_t ) );    memset( id, 0, sizeof(sout_stream_id_t) );    id->id = NULL;    id->p_decoder = NULL;    id->p_encoder = NULL;    /* Create decoder object */    id->p_decoder = vlc_object_create( p_stream, VLC_OBJECT_DECODER );    if( !id->p_decoder )    {        msg_Err( p_stream, "out of memory" );        goto error;    }    vlc_object_attach( id->p_decoder, p_stream );    id->p_decoder->p_module = NULL;    id->p_decoder->fmt_in = *p_fmt;    id->p_decoder->b_pace_control = VLC_TRUE;    /* Create encoder object */    id->p_encoder = vlc_object_create( p_stream, VLC_OBJECT_ENCODER );    if( !id->p_encoder )    {        msg_Err( p_stream, "out of memory" );        goto error;    }    vlc_object_attach( id->p_encoder, p_stream );    id->p_encoder->p_module = NULL;    /* Create destination format */    es_format_Init( &id->p_encoder->fmt_out, p_fmt->i_cat, 0 );    id->p_encoder->fmt_out.i_id    = p_fmt->i_id;    id->p_encoder->fmt_out.i_group = p_fmt->i_group;    if( p_fmt->psz_language )        id->p_encoder->fmt_out.psz_language = strdup( p_fmt->psz_language );    if( p_fmt->i_cat == AUDIO_ES && (p_sys->i_acodec || p_sys->psz_aenc) )    {        msg_Dbg( p_stream,                 "creating audio transcoding from fcc=`%4.4s' to fcc=`%4.4s'",                 (char*)&p_fmt->i_codec, (char*)&p_sys->i_acodec );        /* Complete destination format */        id->p_encoder->fmt_out.i_codec = p_sys->i_acodec;        id->p_encoder->fmt_out.audio.i_rate = p_sys->i_sample_rate > 0 ?            p_sys->i_sample_rate : (int)p_fmt->audio.i_rate;        id->p_encoder->fmt_out.i_bitrate = p_sys->i_abitrate;        id->p_encoder->fmt_out.audio.i_bitspersample =            p_fmt->audio.i_bitspersample;        id->p_encoder->fmt_out.audio.i_channels = p_sys->i_channels > 0 ?            p_sys->i_channels : p_fmt->audio.i_channels;        /* Sanity check for audio channels */        id->p_encoder->fmt_out.audio.i_channels =            __MIN( id->p_encoder->fmt_out.audio.i_channels,                   id->p_decoder->fmt_in.audio.i_channels );        id->p_encoder->fmt_out.audio.i_original_channels =            id->p_decoder->fmt_in.audio.i_physical_channels;        if( id->p_decoder->fmt_in.audio.i_channels ==            id->p_encoder->fmt_out.audio.i_channels )        {            id->p_encoder->fmt_out.audio.i_physical_channels =                id->p_decoder->fmt_in.audio.i_physical_channels;        }        else        {            id->p_encoder->fmt_out.audio.i_physical_channels =                pi_channels_maps[id->p_encoder->fmt_out.audio.i_channels];        }        /* Build decoder -> filter -> encoder chain */        if( transcode_audio_new( p_stream, id ) )        {            msg_Err( p_stream, "cannot create audio chain" );            goto error;        }        /* Open output stream */        id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );        id->b_transcode = VLC_TRUE;        if( !id->id )        {            transcode_audio_close( p_stream, id );            goto error;        }        date_Init( &id->interpolated_pts, p_fmt->audio.i_rate, 1 );    }    else if( p_fmt->i_cat == VIDEO_ES &&             (p_sys->i_vcodec != 0 || p_sys->psz_venc) )    {        msg_Dbg( p_stream,                 "creating video transcoding from fcc=`%4.4s' to fcc=`%4.4s'",                 (char*)&p_fmt->i_codec, (char*)&p_sys->i_vcodec );        /* Complete destination format */        id->p_encoder->fmt_out.i_codec = p_sys->i_vcodec;        id->p_encoder->fmt_out.video.i_width  = p_sys->i_width & ~1;        id->p_encoder->fmt_out.video.i_height = p_sys->i_height & ~1;        id->p_encoder->fmt_out.i_bitrate = p_sys->i_vbitrate;        /* Build decoder -> filter -> encoder chain */        if( transcode_video_new( p_stream, id ) )        {            msg_Err( p_stream, "cannot create video chain" );            goto error;        }        /* Stream will be added later on because we don't know         * all the characteristics of the decoded stream yet */        id->b_transcode = VLC_TRUE;        if( p_sys->f_fps > 0 )        {            id->p_encoder->fmt_out.video.i_frame_rate =                (p_sys->f_fps * 1001) + 0.5;            id->p_encoder->fmt_out.video.i_frame_rate_base = 1001;        }    }    else if( p_fmt->i_cat == SPU_ES && (p_sys->i_scodec || p_sys->psz_senc) )    {        msg_Dbg( p_stream, "creating subtitles transcoding from fcc=`%4.4s' "                 "to fcc=`%4.4s'", (char*)&p_fmt->i_codec,                 (char*)&p_sys->i_scodec );        /* Complete destination format */        id->p_encoder->fmt_out.i_codec = p_sys->i_scodec;        /* build decoder -> filter -> encoder */        if( transcode_spu_new( p_stream, id ) )        {            msg_Err( p_stream, "cannot create subtitles chain" );            goto error;        }        /* open output stream */        id->id = p_sys->p_out->pf_add( p_sys->p_out, &id->p_encoder->fmt_out );        id->b_transcode = VLC_TRUE;        if( !id->id )        {            transcode_spu_close( p_stream, id );            goto error;        }    }    else if( p_fmt->i_cat == SPU_ES && p_sys->b_soverlay )    {        msg_Dbg( p_stream, "subtitles (fcc=`%4.4s') overlaying",                 (char*)&p_fmt->i_codec );        id->b_transcode = VLC_TRUE;        /* Build decoder -> filter -> overlaying chain */        if( transcode_spu_new( p_stream, id ) )        {            msg_Err( p_stream, "cannot create subtitles chain" );            goto error;        }    }    else    {        msg_Dbg( p_stream, "not transcoding a stream (fcc=`%4.4s')",                 (char*)&p_fmt->i_codec );        id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt );        id->b_transcode = VLC_FALSE;        if( !id->id ) goto error;    }    if( p_sys->b_sout_osd )    {        /* Create a fake OSD menu elementary stream */        if( !p_sys->b_es_osd && (p_sys->i_osdcodec != 0 || p_sys->psz_osdenc) )        {            if( transcode_osd_new( p_stream, p_sys->id_osd ) )            {                msg_Err( p_stream, "cannot create osd chain" );                goto error;            }            p_sys->b_es_osd = VLC_TRUE;        }    }    return id; error:    if( id->p_decoder )    {        vlc_object_detach( id->p_decoder );        vlc_object_destroy( id->p_decoder );    }    if( id->p_encoder )    {        vlc_object_detach( id->p_encoder );        es_format_Clean( &id->p_encoder->fmt_out );        vlc_object_destroy( id->p_encoder );    }    free( id );    return NULL;}static int Del( sout_stream_t *p_stream, sout_stream_id_t *id ){    sout_stream_sys_t *p_sys = p_stream->p_sys;    if( p_sys->b_es_osd )        transcode_osd_close( p_stream, p_sys->id_osd );    if( id->b_transcode )    {        switch( id->p_decoder->fmt_in.i_cat )        {        case AUDIO_ES:            transcode_audio_close( p_stream, id );            break;        case VIDEO_ES:            transcode_video_close( p_stream, id );            break;        case SPU_ES:            transcode_spu_close( p_stream, id );            break;        }    }    if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id );    if( id->p_decoder )    {        vlc_object_detach( id->p_decoder );        vlc_object_destroy( id->p_decoder );    }    if( id->p_encoder )    {        vlc_object_detach( id->p_encoder );

⌨️ 快捷键说明

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