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

📄 transcode.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Close encoder */    if( id->p_encoder->p_module )        module_Unneed( id->p_encoder, id->p_encoder->p_module );    /* Close filters */    for( i = 0; i < id->i_filter; i++ )    {        vlc_object_detach( id->pp_filter[i] );        if( id->pp_filter[i]->p_module )            module_Unneed( id->pp_filter[i], id->pp_filter[i]->p_module );        /* Clean-up pictures ring buffer */        for( j = 0; j < PICTURE_RING_SIZE; j++ )        {            if( id->pp_filter[i]->p_owner->pp_pics[j] )                video_del_buffer( VLC_OBJECT(id->pp_filter[i]),                                  id->pp_filter[i]->p_owner->pp_pics[j] );        }        free( id->pp_filter[i]->p_owner );        vlc_object_destroy( id->pp_filter[i] );    }}static int transcode_video_process( sout_stream_t *p_stream,                                    sout_stream_id_t *id,                                    block_t *in, block_t **out ){    sout_stream_sys_t *p_sys = p_stream->p_sys;    int i_duplicate = 1, i;    picture_t *p_pic;    *out = NULL;    while( (p_pic = id->p_decoder->pf_decode_video( id->p_decoder, &in )) )    {        subpicture_t *p_subpic = 0;        if( p_stream->p_sout->i_out_pace_nocontrol && p_sys->b_hurry_up )        {            mtime_t current_date = mdate();            if( current_date + 50000 > p_pic->date )            {                msg_Dbg( p_stream, "late picture skipped ("I64Fd")",                         current_date + 50000 - p_pic->date );                p_pic->pf_release( p_pic );                continue;            }        }        if( p_sys->b_master_sync )        {            mtime_t i_video_drift;            mtime_t i_master_drift = p_sys->i_master_drift;            mtime_t i_pts;            if( !i_master_drift )            {                /* No audio track ? */                p_sys->i_master_drift = i_master_drift = p_pic->date;            }            i_pts = date_Get( &id->interpolated_pts ) + 1;            i_video_drift = p_pic->date - i_pts;            i_duplicate = 1;            /* Set the pts of the frame being encoded */            p_pic->date = i_pts;            if( i_video_drift < i_master_drift - 50000 )            {#if 0                msg_Dbg( p_stream, "dropping frame (%i)",                         (int)(i_video_drift - i_master_drift) );#endif                p_pic->pf_release( p_pic );                continue;            }            else if( i_video_drift > i_master_drift + 50000 )            {#if 0                msg_Dbg( p_stream, "adding frame (%i)",                         (int)(i_video_drift - i_master_drift) );#endif                i_duplicate = 2;            }        }        if( !id->p_encoder->p_module )        {            if( transcode_video_encoder_open( p_stream, id ) != VLC_SUCCESS )            {                p_pic->pf_release( p_pic );                transcode_video_close( p_stream, id );                id->b_transcode = VLC_FALSE;                return VLC_EGENERIC;            }            /* Deinterlace */            if( p_stream->p_sys->b_deinterlace )            {                id->pp_filter[id->i_filter] =                    vlc_object_create( p_stream, VLC_OBJECT_FILTER );                vlc_object_attach( id->pp_filter[id->i_filter], p_stream );                id->pp_filter[id->i_filter]->pf_vout_buffer_new =                    video_new_buffer_filter;                id->pp_filter[id->i_filter]->pf_vout_buffer_del =                    video_del_buffer_filter;                id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;                id->pp_filter[id->i_filter]->fmt_out = id->p_decoder->fmt_out;                id->pp_filter[id->i_filter]->p_cfg = p_sys->p_deinterlace_cfg;                id->pp_filter[id->i_filter]->p_module =                    module_Need( id->pp_filter[id->i_filter],                                 "video filter2", p_sys->psz_deinterlace, 0 );                if( id->pp_filter[id->i_filter]->p_module )                {                    id->pp_filter[id->i_filter]->p_owner =                        malloc( sizeof(filter_owner_sys_t) );                    for( i = 0; i < PICTURE_RING_SIZE; i++ )                        id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;                    id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys;                    id->i_filter++;                }                else                {                    msg_Dbg( p_stream, "no video filter found" );                    vlc_object_detach( id->pp_filter[id->i_filter] );                    vlc_object_destroy( id->pp_filter[id->i_filter] );                }            }            /* Check if we need a filter for chroma conversion or resizing */            if( id->p_decoder->fmt_out.video.i_chroma !=                id->p_encoder->fmt_in.video.i_chroma ||                id->p_decoder->fmt_out.video.i_width !=                id->p_encoder->fmt_out.video.i_width ||                id->p_decoder->fmt_out.video.i_height !=                id->p_encoder->fmt_out.video.i_height ||                p_sys->i_crop_top > 0 || p_sys->i_crop_bottom > 0 ||                p_sys->i_crop_left > 0 || p_sys->i_crop_right > 0 )            {                id->pp_filter[id->i_filter] =                    vlc_object_create( p_stream, VLC_OBJECT_FILTER );                vlc_object_attach( id->pp_filter[id->i_filter], p_stream );                id->pp_filter[id->i_filter]->pf_vout_buffer_new =                    video_new_buffer_filter;                id->pp_filter[id->i_filter]->pf_vout_buffer_del =                    video_del_buffer_filter;                id->pp_filter[id->i_filter]->fmt_in = id->p_decoder->fmt_out;                id->pp_filter[id->i_filter]->fmt_out = id->p_encoder->fmt_in;                id->pp_filter[id->i_filter]->p_cfg = NULL;                id->pp_filter[id->i_filter]->p_module =                    module_Need( id->pp_filter[id->i_filter],                                 "video filter2", 0, 0 );                if( id->pp_filter[id->i_filter]->p_module )                {                    id->pp_filter[id->i_filter]->p_owner =                        malloc( sizeof(filter_owner_sys_t) );                    for( i = 0; i < PICTURE_RING_SIZE; i++ )                        id->pp_filter[id->i_filter]->p_owner->pp_pics[i] = 0;                    id->pp_filter[id->i_filter]->p_owner->p_sys = p_sys;                    id->i_filter++;                }                else                {                    msg_Dbg( p_stream, "no video filter found" );                    vlc_object_detach( id->pp_filter[id->i_filter] );                    vlc_object_destroy( id->pp_filter[id->i_filter] );                    p_pic->pf_release( p_pic );                    transcode_video_close( p_stream, id );                    id->b_transcode = VLC_FALSE;                    return VLC_EGENERIC;                }            }        }        /* Run filter chain */        for( i = 0; i < id->i_filter; i++ )        {            p_pic = id->pp_filter[i]->pf_video_filter(id->pp_filter[i], p_pic);        }        /*         * Encoding         */        /* Check if we have a subpicture to overlay */        if( p_sys->p_spu )        {            p_subpic = spu_SortSubpictures( p_sys->p_spu, p_pic->date );            /* TODO: get another pic */        }        /* Overlay subpicture */        if( p_subpic )        {            int i_scale_width, i_scale_height;            video_format_t *p_fmt;            i_scale_width = id->p_encoder->fmt_in.video.i_width * 1000 /                id->p_decoder->fmt_out.video.i_width;            i_scale_height = id->p_encoder->fmt_in.video.i_height * 1000 /                id->p_decoder->fmt_out.video.i_height;            if( p_pic->i_refcount && !id->i_filter )            {                /* We can't modify the picture, we need to duplicate it */                picture_t *p_tmp = video_new_buffer_decoder( id->p_decoder );                if( p_tmp )                {                    vout_CopyPicture( p_stream, p_tmp, p_pic );                    p_pic->pf_release( p_pic );                    p_pic = p_tmp;                }            }            if( id->i_filter )                p_fmt = &id->pp_filter[id->i_filter -1]->fmt_out.video;            else                p_fmt = &id->p_decoder->fmt_out.video;            /* FIXME (shouldn't have to be done here) */            p_fmt->i_sar_num = p_fmt->i_aspect *                p_fmt->i_height / p_fmt->i_width;            p_fmt->i_sar_den = VOUT_ASPECT_FACTOR;            spu_RenderSubpictures( p_sys->p_spu, p_fmt, p_pic, p_pic, p_subpic,                                   i_scale_width, i_scale_height );        }        if( p_sys->i_threads >= 1 )        {            vlc_mutex_lock( &p_sys->lock_out );            p_sys->pp_pics[p_sys->i_last_pic++] = p_pic;            p_sys->i_last_pic %= PICTURE_RING_SIZE;            *out = p_sys->p_buffers;            p_sys->p_buffers = NULL;            vlc_cond_signal( &p_sys->cond );            vlc_mutex_unlock( &p_sys->lock_out );        }        else        {            block_t *p_block;            p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );            block_ChainAppend( out, p_block );            if( p_sys->b_master_sync )                date_Increment( &id->interpolated_pts, 1 );            if( p_sys->b_master_sync && i_duplicate > 1 )            {                mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;                date_Increment( &id->interpolated_pts, 1 );                p_pic->date = i_pts;                p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);                block_ChainAppend( out, p_block );            }            p_pic->pf_release( p_pic );        }    }    return VLC_SUCCESS;}static int EncoderThread( sout_stream_sys_t *p_sys ){    sout_stream_id_t *id = p_sys->id_video;    picture_t *p_pic;    while( !p_sys->b_die && !p_sys->b_error )    {        block_t *p_block;        vlc_mutex_lock( &p_sys->lock_out );        while( p_sys->i_last_pic == p_sys->i_first_pic )        {            vlc_cond_wait( &p_sys->cond, &p_sys->lock_out );            if( p_sys->b_die || p_sys->b_error ) break;        }        if( p_sys->b_die || p_sys->b_error )        {            vlc_mutex_unlock( &p_sys->lock_out );            break;        }        p_pic = p_sys->pp_pics[p_sys->i_first_pic++];        p_sys->i_first_pic %= PICTURE_RING_SIZE;        vlc_mutex_unlock( &p_sys->lock_out );        p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic );        vlc_mutex_lock( &p_sys->lock_out );        block_ChainAppend( &p_sys->p_buffers, p_block );        if( p_sys->b_master_sync )            date_Increment( &id->interpolated_pts, 1 );#if 0        if( p_sys->b_master_sync && i_duplicate > 1 )        {            mtime_t i_pts = date_Get( &id->interpolated_pts ) + 1;            date_Increment( &id->interpolated_pts, 1 );            p_pic->date = i_pts;            p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);            block_ChainAppend( &p_sys->p_buffers, p_block );        }#endif        vlc_mutex_unlock( &p_sys->lock_out );        p_pic->pf_release( p_pic );    }    while( p_sys->i_last_pic != p_sys->i_first_pic )    {        p_pic = p_sys->pp_pics[p_sys->i_first_pic++];        p_sys->i_first_pic %= PICTURE_RING_SIZE;        p_pic->pf_release( p_pic );    }    block_ChainRelease( p_sys->p_buffers );    return 0;}struct picture_sys_t{    vlc_object_t *p_owner;};static void video_release_buffer( picture_t *p_pic ){    if( p_pic && !p_pic->i_refcount && p_pic->pf_release && p_pic->p_sys )    {        video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );    }    else if( p_pic && p_pic->i_refcount > 0 ) p_pic->i_refcount--;}static picture_t *video_new_buffer( vlc_object_t *p_this, picture_t **pp_ring,                                    sout_stream_sys_t *p_sys ){    decoder_t *p_dec = (decoder_t *)p_this;    picture_t *p_pic;    int i;    /* Find an empty space in the picture ring buffer */    for( i = 0; i < PICTURE_RING_SIZE; i++ )    {        if( pp_ring[i] != 0 && pp_ring[i]->i_status == DESTROYED_PICTURE )        {            pp_ring[i]->i_status = RESERVED_PICTURE;            return pp_ring[i];        }    }    for( i = 0; i < PICTURE_RING_SIZE; i++ )    {        if( pp_ring[i] == 0 ) break;    }    if( i == PICTURE_RING_SIZE && p_sys->i_threads >= 1 )    {        int i_first_pic = p_sys->i_first_pic;        if( p_sys->i_first_pic != p_sys->i_last_pic )        {            /* Encoder still has stuff to encod

⌨️ 快捷键说明

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