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

📄 vout_subpictures.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
}/** * Allocate a subpicture in the spu heap. * * This function create a reserved subpicture in the spu heap. * A null pointer is returned if the function fails. This method provides an * already allocated zone of memory in the spu data fields. It needs locking * since several pictures can be created by several producers threads. * \param p_spu the subpicture unit in which to create the subpicture * \return NULL on error, a reserved subpicture otherwise */subpicture_t *spu_CreateSubpicture( spu_t *p_spu ){    int                 i_subpic;                        /* subpicture index */    subpicture_t *      p_subpic = NULL;            /* first free subpicture */    /* Get lock */    vlc_mutex_lock( &p_spu->subpicture_lock );    /*     * Look for an empty place     */    p_subpic = NULL;    for( i_subpic = 0; i_subpic < VOUT_MAX_SUBPICTURES; i_subpic++ )    {        if( p_spu->p_subpicture[i_subpic].i_status == FREE_SUBPICTURE )        {            /* Subpicture is empty and ready for allocation */            p_subpic = &p_spu->p_subpicture[i_subpic];            p_spu->p_subpicture[i_subpic].i_status = RESERVED_SUBPICTURE;            break;        }    }    /* If no free subpicture could be found */    if( p_subpic == NULL )    {        msg_Err( p_spu, "subpicture heap is full" );        vlc_mutex_unlock( &p_spu->subpicture_lock );        return NULL;    }    /* Copy subpicture information, set some default values */    memset( p_subpic, 0, sizeof(subpicture_t) );    p_subpic->i_status   = RESERVED_SUBPICTURE;    p_subpic->b_absolute = VLC_TRUE;    p_subpic->b_fade     = VLC_FALSE;    p_subpic->i_alpha    = 0xFF;    p_subpic->p_region   = 0;    p_subpic->pf_render  = 0;    p_subpic->pf_destroy = 0;    p_subpic->p_sys      = 0;    vlc_mutex_unlock( &p_spu->subpicture_lock );    p_subpic->pf_create_region = __spu_CreateRegion;    p_subpic->pf_make_region = __spu_MakeRegion;    p_subpic->pf_destroy_region = __spu_DestroyRegion;        return p_subpic;}/** * Remove a subpicture from the heap * * This function frees a previously reserved subpicture. * It is meant to be used when the construction of a picture aborted. * This function does not need locking since reserved subpictures are ignored * by the spu. */void spu_DestroySubpicture( spu_t *p_spu, subpicture_t *p_subpic ){    /* Get lock */    vlc_mutex_lock( &p_spu->subpicture_lock );    /* There can be race conditions so we need to check the status */    if( p_subpic->i_status == FREE_SUBPICTURE )    {        vlc_mutex_unlock( &p_spu->subpicture_lock );        return;    }    /* Check if status is valid */    if( ( p_subpic->i_status != RESERVED_SUBPICTURE )           && ( p_subpic->i_status != READY_SUBPICTURE ) )    {        msg_Err( p_spu, "subpicture %p has invalid status %d",                         p_subpic, p_subpic->i_status );    }    while( p_subpic->p_region )    {        subpicture_region_t *p_region = p_subpic->p_region;        p_subpic->p_region = p_region->p_next;        spu_DestroyRegion( p_spu, p_region );    }    if( p_subpic->pf_destroy )    {        p_subpic->pf_destroy( p_subpic );    }    p_subpic->i_status = FREE_SUBPICTURE;    vlc_mutex_unlock( &p_spu->subpicture_lock );}/***************************************************************************** * spu_RenderSubpictures: render a subpicture list ***************************************************************************** * This function renders all sub picture units in the list. *****************************************************************************/void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt,                            picture_t *p_pic_dst, picture_t *p_pic_src,                            subpicture_t *p_subpic,                            int i_scale_width_orig, int i_scale_height_orig ){    /* Get lock */    vlc_mutex_lock( &p_spu->subpicture_lock );    /* Check i_status again to make sure spudec hasn't destroyed the subpic */    while( p_subpic != NULL && p_subpic->i_status != FREE_SUBPICTURE )    {        subpicture_region_t *p_region = p_subpic->p_region;        int i_scale_width, i_scale_height;        int i_subpic_x = p_subpic->i_x;        /* Load the blending module */        if( !p_spu->p_blend && p_region )        {            p_spu->p_blend = vlc_object_create( p_spu, VLC_OBJECT_FILTER );            vlc_object_attach( p_spu->p_blend, p_spu );            p_spu->p_blend->fmt_out.video.i_x_offset =                p_spu->p_blend->fmt_out.video.i_y_offset = 0;            p_spu->p_blend->fmt_out.video.i_aspect = p_fmt->i_aspect;            p_spu->p_blend->fmt_out.video.i_chroma = p_fmt->i_chroma;            p_spu->p_blend->fmt_in.video.i_chroma = VLC_FOURCC('Y','U','V','P');            p_spu->p_blend->p_module =                module_Need( p_spu->p_blend, "video blending", 0, 0 );        }        /* Load the text rendering module */        if( !p_spu->p_text && p_region )        {            p_spu->p_text = vlc_object_create( p_spu, VLC_OBJECT_FILTER );            vlc_object_attach( p_spu->p_text, p_spu );            p_spu->p_text->fmt_out.video.i_width =                p_spu->p_text->fmt_out.video.i_visible_width =                    p_fmt->i_width;            p_spu->p_text->fmt_out.video.i_height =                p_spu->p_text->fmt_out.video.i_visible_height =                    p_fmt->i_height;            p_spu->p_text->pf_sub_buffer_new = spu_new_buffer;            p_spu->p_text->pf_sub_buffer_del = spu_del_buffer;            p_spu->p_text->p_module =                module_Need( p_spu->p_text, "text renderer", 0, 0 );        }        else if( p_region )        {            p_spu->p_text->fmt_out.video.i_width =                p_spu->p_text->fmt_out.video.i_visible_width =                    p_fmt->i_width;            p_spu->p_text->fmt_out.video.i_height =                p_spu->p_text->fmt_out.video.i_visible_height =                    p_fmt->i_height;        }        i_scale_width = i_scale_width_orig;        i_scale_height = i_scale_height_orig;        if( p_subpic->i_original_picture_width &&            p_subpic->i_original_picture_height )        {            i_scale_width = i_scale_width * p_fmt->i_width /                             p_subpic->i_original_picture_width;            i_scale_height = i_scale_height * p_fmt->i_height /                             p_subpic->i_original_picture_height;        }        /* Set default subpicture aspect ratio */        if( p_region && p_region->fmt.i_aspect &&            (!p_region->fmt.i_sar_num || !p_region->fmt.i_sar_den) )        {            p_region->fmt.i_sar_den = p_region->fmt.i_aspect;            p_region->fmt.i_sar_num = VOUT_ASPECT_FACTOR;        }        if( p_region &&            (!p_region->fmt.i_sar_num || !p_region->fmt.i_sar_den) )        {            p_region->fmt.i_sar_den = p_fmt->i_sar_den;            p_region->fmt.i_sar_num = p_fmt->i_sar_num;        }        /* Take care of the aspect ratio */        if( p_region && p_region->fmt.i_sar_num * p_fmt->i_sar_den !=            p_region->fmt.i_sar_den * p_fmt->i_sar_num )        {            i_scale_width = i_scale_width *                (int64_t)p_region->fmt.i_sar_num * p_fmt->i_sar_den /                p_region->fmt.i_sar_den / p_fmt->i_sar_num;            i_subpic_x = p_subpic->i_x * i_scale_width / 1000;        }        /* Load the scaling module */        if( !p_spu->p_scale && (i_scale_width != 1000 ||            i_scale_height != 1000) )        {            p_spu->p_scale = vlc_object_create( p_spu, VLC_OBJECT_FILTER );            vlc_object_attach( p_spu->p_scale, p_spu );            p_spu->p_scale->fmt_out.video.i_chroma =                p_spu->p_scale->fmt_in.video.i_chroma =                    VLC_FOURCC('Y','U','V','P');            p_spu->p_scale->fmt_in.video.i_width =                p_spu->p_scale->fmt_in.video.i_height = 32;            p_spu->p_scale->fmt_out.video.i_width =                p_spu->p_scale->fmt_out.video.i_height = 16;            p_spu->p_scale->pf_vout_buffer_new = spu_new_video_buffer;            p_spu->p_scale->pf_vout_buffer_del = spu_del_video_buffer;            p_spu->p_scale->p_module =                module_Need( p_spu->p_scale, "video filter2", 0, 0 );        }        while( p_region && p_spu->p_blend && p_spu->p_blend->pf_video_blend )        {            int i_fade_alpha = 255;            int i_x_offset = p_region->i_x + i_subpic_x;            int i_y_offset = p_region->i_y + p_subpic->i_y;            if( p_region->fmt.i_chroma == VLC_FOURCC('T','E','X','T') )            {                if( p_spu->p_text && p_spu->p_text->p_module &&                    p_spu->p_text->pf_render_text )                {                    p_region->i_text_align = p_subpic->i_flags & 0x3;                    p_spu->p_text->pf_render_text( p_spu->p_text,                                                   p_region, p_region );                 }            }            /* Force palette if requested */            if( p_spu->b_force_palette && VLC_FOURCC('Y','U','V','P') ==                p_region->fmt.i_chroma )            {                memcpy( p_region->fmt.p_palette->palette,                        p_spu->palette, 16 );            }            /* Scale SPU if necessary */            if( p_region->p_cache )            {                if( i_scale_width * p_region->fmt.i_width / 1000 !=                    p_region->p_cache->fmt.i_width ||                    i_scale_height * p_region->fmt.i_height / 1000 !=                    p_region->p_cache->fmt.i_height )                {                    p_subpic->pf_destroy_region( VLC_OBJECT(p_spu),                                                 p_region->p_cache );                    p_region->p_cache = 0;                }            }            if( (i_scale_width != 1000 || i_scale_height != 1000) &&                p_spu->p_scale && !p_region->p_cache )            {                picture_t *p_pic;                p_spu->p_scale->fmt_in.video = p_region->fmt;                p_spu->p_scale->fmt_out.video = p_region->fmt;                p_region->p_cache =                    p_subpic->pf_create_region( VLC_OBJECT(p_spu),                        &p_spu->p_scale->fmt_out.video );                if( p_spu->p_scale->fmt_out.video.p_palette )                    *p_spu->p_scale->fmt_out.video.p_palette =                        *p_region->fmt.p_palette;                p_region->p_cache->p_next = p_region->p_next;                vout_CopyPicture( p_spu, &p_region->p_cache->picture,                                  &p_region->picture );                p_spu->p_scale->fmt_out.video.i_width =                    p_region->fmt.i_width * i_scale_width / 1000;                p_spu->p_scale->fmt_out.video.i_visible_width =                    p_region->fmt.i_visible_width * i_scale_width / 1000;                p_spu->p_scale->fmt_out.video.i_height =                    p_region->fmt.i_height * i_scale_height / 1000;                p_spu->p_scale->fmt_out.video.i_visible_height =                    p_region->fmt.i_visible_height * i_scale_height / 1000;                p_region->p_cache->fmt = p_spu->p_scale->fmt_out.video;                p_region->p_cache->i_x = p_region->i_x * i_scale_width / 1000;                p_region->p_cache->i_y = p_region->i_y * i_scale_height / 1000;                p_pic = p_spu->p_scale->pf_video_filter(                                 p_spu->p_scale, &p_region->p_cache->picture );                if( p_pic )                {                    picture_t p_pic_tmp = p_region->p_cache->picture;                    p_region->p_cache->picture = *p_pic;                    *p_pic = p_pic_tmp;                    free( p_pic );                }            }            if( (i_scale_width != 1000 || i_scale_height != 1000) &&                p_spu->p_scale && p_region->p_cache )            {                p_region = p_region->p_cache;            }            if( p_subpic->i_flags & SUBPICTURE_ALIGN_BOTTOM )            {                i_y_offset = p_fmt->i_height - p_region->fmt.i_height -                    p_subpic->i_y;            }            else if ( !(p_subpic->i_flags & SUBPICTURE_ALIGN_TOP) )            {                i_y_offset = p_fmt->i_height / 2 - p_region->fmt.i_height / 2;            }            if( p_subpic->i_flags & SUBPICTURE_ALIGN_RIGHT )            {                i_x_offset = p_fmt->i_width - p_region->fmt.i_width -                    i_subpic_x;            }            else if ( !(p_subpic->i_flags & SUBPICTURE_ALIGN_LEFT) )            {                i_x_offset = p_fmt->i_width / 2 - p_region->fmt.i_width / 2;            }            if( p_subpic->b_absolute )            {                i_x_offset = p_region->i_x +                    i_subpic_x * i_scale_width / 1000;                i_y_offset = p_region->i_y +                    p_subpic->i_y * i_scale_height / 1000;                if( p_spu->i_margin >= 0 )                {                    if( p_subpic->i_height + (unsigned int)p_spu->i_margin <=                        p_fmt->i_height )                    {                        i_y_offset = p_fmt->i_height -                            p_spu->i_margin - p_subpic->i_height;                    }                }            }            p_spu->p_blend->fmt_in.video = p_region->fmt;            /* Force cropping if requested */            if( p_spu->b_force_crop )            {                video_format_t *p_fmt = &p_spu->p_blend->fmt_in.video;                int i_crop_x = p_spu->i_crop_x * i_scale_width / 1000;

⌨️ 快捷键说明

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