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

📄 mosaic_bridge.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
        if( p_sys->p_decoder->p_module )            module_Unneed( p_sys->p_decoder, p_sys->p_decoder->p_module );        vlc_object_detach( p_sys->p_decoder );        vlc_object_release( p_sys->p_decoder );        picture_t **pp_ring = p_owner->pp_pics;        for( i = 0; i < PICTURE_RING_SIZE; i++ )        {            if ( pp_ring[i] != NULL )            {                free( pp_ring[i]->p_data_orig );                free( pp_ring[i]->p_sys );                free( pp_ring[i] );            }        }        free( p_owner );    }    /* Destroy user specified video filters */    if( p_sys->p_vf2 )        filter_chain_Delete( p_sys->p_vf2 );    vlc_mutex_lock( p_sys->p_lock );    p_bridge = GetBridge( p_stream );    p_es = p_sys->p_es;    p_es->b_empty = true;    while ( p_es->p_picture )    {        picture_t *p_next = p_es->p_picture->p_next;        p_es->p_picture->pf_release( p_es->p_picture );        p_es->p_picture = p_next;    }    for ( i = 0; i < p_bridge->i_es_num; i++ )    {        if ( !p_bridge->pp_es[i]->b_empty )        {            b_last_es = false;            break;        }    }    if ( b_last_es )    {        vlc_object_t *p_libvlc = VLC_OBJECT( p_stream->p_libvlc );        for ( i = 0; i < p_bridge->i_es_num; i++ )            free( p_bridge->pp_es[i] );        free( p_bridge->pp_es );        free( p_bridge );        var_Destroy( p_libvlc, "mosaic-struct" );    }    vlc_mutex_unlock( p_sys->p_lock );    if ( p_sys->p_image )    {        image_HandlerDelete( p_sys->p_image );    }    p_sys->b_inited = false;    return VLC_SUCCESS;}/***************************************************************************** * PushPicture : push a picture in the mosaic-struct structure *****************************************************************************/static void PushPicture( sout_stream_t *p_stream, picture_t *p_picture ){    sout_stream_sys_t *p_sys = p_stream->p_sys;    bridged_es_t *p_es = p_sys->p_es;    vlc_mutex_lock( p_sys->p_lock );    *p_es->pp_last = p_picture;    p_picture->p_next = NULL;    p_es->pp_last = &p_picture->p_next;    vlc_mutex_unlock( p_sys->p_lock );}static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,                 block_t *p_buffer ){    sout_stream_sys_t *p_sys = p_stream->p_sys;    picture_t *p_pic;    if ( (sout_stream_sys_t *)id != p_sys )    {        block_ChainRelease( p_buffer );        return VLC_SUCCESS;    }    while ( (p_pic = p_sys->p_decoder->pf_decode_video( p_sys->p_decoder,                                                        &p_buffer )) )    {        picture_t *p_new_pic;        if( p_sys->i_height || p_sys->i_width )        {            video_format_t fmt_out, fmt_in;            memset( &fmt_in, 0, sizeof(video_format_t) );            memset( &fmt_out, 0, sizeof(video_format_t) );            fmt_in = p_sys->p_decoder->fmt_out.video;            if( p_sys->i_chroma )                fmt_out.i_chroma = p_sys->i_chroma;            else                fmt_out.i_chroma = VLC_FOURCC('I','4','2','0');            if ( !p_sys->i_height )            {                fmt_out.i_width = p_sys->i_width;                fmt_out.i_height = (p_sys->i_width * VOUT_ASPECT_FACTOR                    * p_sys->i_sar_num / p_sys->i_sar_den / fmt_in.i_aspect)                      & ~0x1;            }            else if ( !p_sys->i_width )            {                fmt_out.i_height = p_sys->i_height;                fmt_out.i_width = (p_sys->i_height * fmt_in.i_aspect                    * p_sys->i_sar_den / p_sys->i_sar_num / VOUT_ASPECT_FACTOR)                      & ~0x1;            }            else            {                fmt_out.i_width = p_sys->i_width;                fmt_out.i_height = p_sys->i_height;            }            fmt_out.i_visible_width = fmt_out.i_width;            fmt_out.i_visible_height = fmt_out.i_height;            p_new_pic = image_Convert( p_sys->p_image,                                       p_pic, &fmt_in, &fmt_out );            if ( p_new_pic == NULL )            {                msg_Err( p_stream, "image conversion failed" );                picture_Release( p_pic );                continue;            }        }        else        {            /* TODO: chroma conversion if needed */            p_new_pic = (picture_t*)malloc( sizeof(picture_t) );            if( p_new_pic == NULL )            {                msg_Err( p_stream, "image conversion failed" );                continue;            }            if( vout_AllocatePicture(                                  p_stream, p_new_pic, p_pic->format.i_chroma,                                  p_pic->format.i_width, p_pic->format.i_height,                                  p_sys->p_decoder->fmt_out.video.i_aspect )                != VLC_SUCCESS )            {                picture_Release( p_pic );                free( p_new_pic );                msg_Err( p_stream, "image allocation failed" );                continue;            }            vout_CopyPicture( p_stream, p_new_pic, p_pic );        }        p_new_pic->i_refcount = 1;        p_new_pic->i_status = DESTROYED_PICTURE;        p_new_pic->i_type   = DIRECT_PICTURE;        p_new_pic->p_sys = (picture_sys_t *)p_new_pic->pf_release;        p_new_pic->pf_release = ReleasePicture;        p_new_pic->date = p_pic->date;        picture_Release( p_pic );        if( p_sys->p_vf2 )            p_new_pic = filter_chain_VideoFilter( p_sys->p_vf2, p_new_pic );        PushPicture( p_stream, p_new_pic );    }    return VLC_SUCCESS;}struct picture_sys_t{    vlc_object_t *p_owner;    bool b_dead;};static void video_release_buffer_decoder( picture_t *p_pic ){    assert( p_pic && p_pic->p_sys );    if( --p_pic->i_refcount > 0 )        return;    video_del_buffer_decoder( (decoder_t *)p_pic->p_sys->p_owner, p_pic );}static void video_release_buffer_filter( picture_t *p_pic ){    assert( p_pic );    if( --p_pic->i_refcount > 0 )        return;    assert( p_pic->p_sys );    video_del_buffer_filter( (filter_t *)p_pic->p_sys->p_owner, p_pic );}inline static picture_t *video_new_buffer_decoder( decoder_t *p_dec ){    return video_new_buffer( VLC_OBJECT( p_dec ),                             (decoder_owner_sys_t *)p_dec->p_owner,                             &p_dec->fmt_out,                             video_release_buffer_decoder );}inline static picture_t *video_new_buffer_filter( filter_t *p_filter ){    return video_new_buffer( VLC_OBJECT( p_filter ),                             (decoder_owner_sys_t *)p_filter->p_owner,                             &p_filter->fmt_out,                             video_release_buffer_filter );}static picture_t *video_new_buffer( vlc_object_t *p_this,                                    decoder_owner_sys_t *p_sys,                                    es_format_t *fmt_out,                                    void ( *pf_release )( picture_t * ) ){    picture_t **pp_ring = p_sys->pp_pics;    picture_t *p_pic;    int i;    if( fmt_out->video.i_width != p_sys->video.i_width ||        fmt_out->video.i_height != p_sys->video.i_height ||        fmt_out->video.i_chroma != p_sys->video.i_chroma ||        fmt_out->video.i_aspect != p_sys->video.i_aspect )    {        if( !fmt_out->video.i_sar_num ||            !fmt_out->video.i_sar_den )        {            fmt_out->video.i_sar_num =                fmt_out->video.i_aspect * fmt_out->video.i_height;            fmt_out->video.i_sar_den =                VOUT_ASPECT_FACTOR * fmt_out->video.i_width;        }        vlc_ureduce( &fmt_out->video.i_sar_num,                     &fmt_out->video.i_sar_den,                     fmt_out->video.i_sar_num,                     fmt_out->video.i_sar_den, 0 );        if( !fmt_out->video.i_visible_width ||            !fmt_out->video.i_visible_height )        {            fmt_out->video.i_visible_width = fmt_out->video.i_width;            fmt_out->video.i_visible_height = fmt_out->video.i_height;        }        fmt_out->video.i_chroma = fmt_out->i_codec;        p_sys->video = fmt_out->video;        for( i = 0; i < PICTURE_RING_SIZE; i++ )        {            if ( pp_ring[i] != NULL )            {                if ( pp_ring[i]->i_status == DESTROYED_PICTURE )                {                    free( pp_ring[i]->p_data_orig );                    free( pp_ring[i]->p_sys );                    free( pp_ring[i] );                }                else                {                    pp_ring[i]->p_sys->b_dead = true;                }                pp_ring[i] = NULL;            }        }    }    /* Find an empty space in the picture ring buffer */    for( i = 0; i < PICTURE_RING_SIZE; i++ )    {        if( pp_ring[i] != NULL && pp_ring[i]->i_status == DESTROYED_PICTURE )        {            pp_ring[i]->i_status = RESERVED_PICTURE;            pp_ring[i]->i_refcount = 1;            return pp_ring[i];        }    }    for( i = 0; i < PICTURE_RING_SIZE; i++ )    {        if( pp_ring[i] == NULL ) break;    }    if( i == PICTURE_RING_SIZE )    {        msg_Err( p_this, "decoder/filter is leaking pictures, "                 "resetting its ring buffer" );        for( i = 0; i < PICTURE_RING_SIZE; i++ )        {            pp_ring[i]->p_sys->b_dead = true;            pp_ring[i]->pf_release( pp_ring[i] );            pp_ring[i] = NULL;        }        i = 0;    }    p_pic = malloc( sizeof(picture_t) );    if( !p_pic ) return NULL;    fmt_out->video.i_chroma = fmt_out->i_codec;    if( vout_AllocatePicture( p_this, p_pic,                          fmt_out->video.i_chroma,                          fmt_out->video.i_width,                          fmt_out->video.i_height,                          fmt_out->video.i_aspect ) != VLC_SUCCESS )    {        free( p_pic );        return NULL;    }    if( !p_pic->i_planes )    {        free( p_pic );        return NULL;    }    p_pic->pf_release = pf_release;    p_pic->i_refcount = 1;    p_pic->p_sys = malloc( sizeof(picture_sys_t) );    p_pic->p_sys->p_owner = p_this;    p_pic->p_sys->b_dead = false;    p_pic->i_status = RESERVED_PICTURE;    pp_ring[i] = p_pic;    return p_pic;}inline static void video_del_buffer_decoder( decoder_t *p_this,                                             picture_t *p_pic ){    VLC_UNUSED(p_this);    video_del_buffer( p_pic );}inline static void video_del_buffer_filter( filter_t *p_this,                                            picture_t *p_pic ){    VLC_UNUSED(p_this);    video_del_buffer( p_pic );}static void video_del_buffer( picture_t *p_pic ){    p_pic->i_refcount = 0;    p_pic->i_status = DESTROYED_PICTURE;    if ( p_pic->p_sys->b_dead )    {        free( p_pic->p_data_orig );        free( p_pic->p_sys );        free( p_pic );    }}static void video_link_picture_decoder( decoder_t *p_dec, picture_t *p_pic ){    VLC_UNUSED(p_dec);    p_pic->i_refcount++;}static void video_unlink_picture_decoder( decoder_t *p_dec, picture_t *p_pic ){    VLC_UNUSED(p_dec);    video_release_buffer_decoder( p_pic );}/********************************************************************** * Callback to update (some) params on the fly **********************************************************************/static int HeightCallback( vlc_object_t *p_this, char const *psz_var,                           vlc_value_t oldval, vlc_value_t newval,                           void *p_data ){    VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(psz_var);    sout_stream_t *p_stream = (sout_stream_t *)p_data;    sout_stream_sys_t *p_sys = p_stream->p_sys;    /* We create the handler before updating the value in p_sys     * so we don't have to worry about locking */    if( !p_sys->p_image && newval.i_int )        p_sys->p_image = image_HandlerCreate( p_stream );    p_sys->i_height = newval.i_int;    return VLC_SUCCESS;}static int WidthCallback( vlc_object_t *p_this, char const *psz_var,                           vlc_value_t oldval, vlc_value_t newval,                           void *p_data ){    VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(psz_var);    sout_stream_t *p_stream = (sout_stream_t *)p_data;    sout_stream_sys_t *p_sys = p_stream->p_sys;    /* We create the handler before updating the value in p_sys     * so we don't have to worry about locking */    if( !p_sys->p_image && newval.i_int )        p_sys->p_image = image_HandlerCreate( p_stream );    p_sys->i_width = newval.i_int;    return VLC_SUCCESS;}static int alphaCallback( vlc_object_t *p_this, char const *psz_var,                          vlc_value_t oldval, vlc_value_t newval,                          void *p_data ){    VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(psz_var);    sout_stream_t *p_stream = (sout_stream_t *)p_data;    sout_stream_sys_t *p_sys = p_stream->p_sys;    if( p_sys->p_es )        p_sys->p_es->i_alpha = newval.i_int;    return VLC_SUCCESS;}static int xCallback( vlc_object_t *p_this, char const *psz_var,                      vlc_value_t oldval, vlc_value_t newval,                      void *p_data ){    VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(psz_var);    sout_stream_t *p_stream = (sout_stream_t *)p_data;    sout_stream_sys_t *p_sys = p_stream->p_sys;    if( p_sys->p_es )        p_sys->p_es->i_x = newval.i_int;    return VLC_SUCCESS;}static int yCallback( vlc_object_t *p_this, char const *psz_var,                      vlc_value_t oldval, vlc_value_t newval,                      void *p_data ){    VLC_UNUSED(p_this); VLC_UNUSED(oldval); VLC_UNUSED(psz_var);    sout_stream_t *p_stream = (sout_stream_t *)p_data;    sout_stream_sys_t *p_sys = p_stream->p_sys;    if( p_sys->p_es )        p_sys->p_es->i_y = newval.i_int;    return VLC_SUCCESS;}

⌨️ 快捷键说明

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