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

📄 vout_subpictures.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
                                            &p_scale->fmt_out.video );            p_region->p_cache->p_next = p_region->p_next;            if( p_scale->fmt_out.video.p_palette )                *p_scale->fmt_out.video.p_palette =                    *p_region->fmt.p_palette;            vout_CopyPicture( p_spu, &p_region->p_cache->picture,                              &p_region->picture );            p_scale->fmt_out.video.i_width = i_dst_width;            p_scale->fmt_out.video.i_height = i_dst_height;            p_scale->fmt_out.video.i_visible_width =                p_region->fmt.i_visible_width * pi_scale_width[ i_scale_idx ] / 1000;            p_scale->fmt_out.video.i_visible_height =                p_region->fmt.i_visible_height * pi_scale_height[ i_scale_idx ] / 1000;            p_region->p_cache->fmt = p_scale->fmt_out.video;            p_region->p_cache->i_x = p_region->i_x * pi_scale_width[ i_scale_idx ] / 1000;            p_region->p_cache->i_y = p_region->i_y * pi_scale_height[ i_scale_idx ] / 1000;            p_region->p_cache->i_align = p_region->i_align;            p_region->p_cache->i_alpha = p_region->i_alpha;            p_pic = NULL;            if( p_scale->p_module )                p_pic = p_scale->pf_video_filter( p_scale, &p_region->p_cache->picture );            else                msg_Err( p_spu, "scaling failed (module not loaded)" );            if( p_pic )            {                p_region->p_cache->picture = *p_pic;                free( p_pic );            }            else            {                p_subpic->pf_destroy_region( VLC_OBJECT(p_spu),                                             p_region->p_cache );                p_region->p_cache = NULL;            }        }        /* And use the scaled picture */        if( p_region->p_cache )        {            p_region = p_region->p_cache;            fmt_original = p_region->fmt;        }    }    if( p_region->i_align & SUBPICTURE_ALIGN_BOTTOM )    {        i_y_offset = p_fmt->i_height - p_region->fmt.i_height -            (p_subpic->i_y + p_region->i_y) * i_inv_scale_y / 1000;    }    else if ( !(p_region->i_align & SUBPICTURE_ALIGN_TOP) )    {        i_y_offset = p_fmt->i_height / 2 - p_region->fmt.i_height / 2;    }    if( p_region->i_align & SUBPICTURE_ALIGN_RIGHT )    {        i_x_offset = p_fmt->i_width - p_region->fmt.i_width -            (pi_subpic_x[ i_scale_idx ] + p_region->i_x)            * i_inv_scale_x / 1000;    }    else if ( !(p_region->i_align & 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 +            pi_subpic_x[ i_scale_idx ] *                             pi_scale_width[ i_scale_idx ] / 1000)            * i_inv_scale_x / 1000;        i_y_offset = (p_region->i_y +            p_subpic->i_y * pi_scale_height[ i_scale_idx ] / 1000)            * i_inv_scale_y / 1000;    }    i_x_offset = __MAX( i_x_offset, 0 );    i_y_offset = __MAX( i_y_offset, 0 );    if( p_spu->i_margin != 0 && !b_force_crop )    {        int i_diff = 0;        int i_low = (i_y_offset - p_spu->i_margin) * i_inv_scale_y / 1000;        int i_high = i_low + p_region->fmt.i_height;        /* crop extra margin to keep within bounds */        if( i_low < 0 )            i_diff = i_low;        if( i_high > (int)p_fmt->i_height )            i_diff = i_high - p_fmt->i_height;        i_y_offset -= ( p_spu->i_margin * i_inv_scale_y / 1000 + i_diff );    }    /* Force cropping if requested */    if( b_force_crop )    {        video_format_t *p_fmt = &p_region->fmt;        int i_crop_x = p_spu->i_crop_x * pi_scale_width[ i_scale_idx ] / 1000                            * i_inv_scale_x / 1000;        int i_crop_y = p_spu->i_crop_y * pi_scale_height[ i_scale_idx ] / 1000                            * i_inv_scale_y / 1000;        int i_crop_width = p_spu->i_crop_width * pi_scale_width[ i_scale_idx ] / 1000                            * i_inv_scale_x / 1000;        int i_crop_height = p_spu->i_crop_height * pi_scale_height[ i_scale_idx ] / 1000                            * i_inv_scale_y / 1000;        /* Find the intersection */        if( i_crop_x + i_crop_width <= i_x_offset ||            i_x_offset + (int)p_fmt->i_visible_width < i_crop_x ||            i_crop_y + i_crop_height <= i_y_offset ||            i_y_offset + (int)p_fmt->i_visible_height < i_crop_y )        {            /* No intersection */            p_fmt->i_visible_width = p_fmt->i_visible_height = 0;        }        else        {            int i_x, i_y, i_x_end, i_y_end;            i_x = __MAX( i_crop_x, i_x_offset );            i_y = __MAX( i_crop_y, i_y_offset );            i_x_end = __MIN( i_crop_x + i_crop_width,                           i_x_offset + (int)p_fmt->i_visible_width );            i_y_end = __MIN( i_crop_y + i_crop_height,                           i_y_offset + (int)p_fmt->i_visible_height );            p_fmt->i_x_offset = i_x - i_x_offset;            p_fmt->i_y_offset = i_y - i_y_offset;            p_fmt->i_visible_width = i_x_end - i_x;            p_fmt->i_visible_height = i_y_end - i_y;            i_x_offset = i_x;            i_y_offset = i_y;        }        b_restore_format = true;    }    i_x_offset = __MAX( i_x_offset, 0 );    i_y_offset = __MAX( i_y_offset, 0 );    /* Compute alpha blend value */    i_fade_alpha = 255;    if( p_subpic->b_fade )    {        mtime_t i_fade_start = ( p_subpic->i_stop +                                 p_subpic->i_start ) / 2;        mtime_t i_now = mdate();        if( i_now >= i_fade_start && p_subpic->i_stop > i_fade_start )        {            i_fade_alpha = 255 * ( p_subpic->i_stop - i_now ) /                           ( p_subpic->i_stop - i_fade_start );        }    }    /* Update the blender */    SpuRenderUpdateBlend( p_spu, p_fmt->i_width, p_fmt->i_height, &p_region->fmt );    if( p_spu->p_blend->p_module )    {        p_spu->p_blend->pf_video_blend( p_spu->p_blend, p_pic_dst,            p_pic_src, &p_region->picture, i_x_offset, i_y_offset,            i_fade_alpha * p_subpic->i_alpha * p_region->i_alpha / 65025 );    }    else    {        msg_Err( p_spu, "blending %4.4s to %4.4s failed",                 (char *)&p_spu->p_blend->fmt_out.video.i_chroma,                 (char *)&p_spu->p_blend->fmt_out.video.i_chroma );    }exit:    if( b_rerender_text )    {        /* Some forms of subtitles need to be re-rendered more than         * once, eg. karaoke. We therefore restore the region to its         * pre-rendered state, so the next time through everything is         * calculated again.         */        p_region->picture.pf_release( &p_region->picture );        memset( &p_region->picture, 0, sizeof( picture_t ) );        p_region->i_align &= ~SUBPICTURE_RENDERED;    }    if( b_restore_format )        p_region->fmt = fmt_original;}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 ){    int i_source_video_width;    int i_source_video_height;    subpicture_t *p_subpic_v;    /* Get lock */    vlc_mutex_lock( &p_spu->subpicture_lock );    for( p_subpic_v = p_subpic;            p_subpic_v != NULL && p_subpic_v->i_status != FREE_SUBPICTURE;            p_subpic_v = p_subpic_v->p_next )    {        if( p_subpic_v->pf_pre_render )            p_subpic_v->pf_pre_render( p_fmt, p_spu, p_subpic_v );    }    if( i_scale_width_orig <= 0 )        i_scale_width_orig = 1000;    if( i_scale_height_orig <= 0 )        i_scale_height_orig = 1000;    i_source_video_width  = p_fmt->i_width  * 1000 / i_scale_width_orig;    i_source_video_height = p_fmt->i_height * 1000 / i_scale_height_orig;    /* Check i_status again to make sure spudec hasn't destroyed the subpic */    for( ; ( p_subpic != NULL ) && ( p_subpic->i_status != FREE_SUBPICTURE ); p_subpic = p_subpic->p_next )    {        subpicture_region_t *p_region;        int pi_scale_width[ SCALE_SIZE ];        int pi_scale_height[ SCALE_SIZE ];        int pi_subpic_x[ SCALE_SIZE ];        int k;        /* If the source video and subtitles stream agree on the size of         * the video then disregard all further references to the subtitle         * stream.         */        if( ( i_source_video_height == p_subpic->i_original_picture_height ) &&            ( i_source_video_width  == p_subpic->i_original_picture_width ) )        {            /* FIXME this looks wrong */            p_subpic->i_original_picture_height = 0;            p_subpic->i_original_picture_width = 0;        }        for( k = 0; k < SCALE_SIZE ; k++ )            pi_subpic_x[ k ] = p_subpic->i_x;        if( p_subpic->pf_update_regions )        {            /* TODO do not reverse the scaling that was done before calling             * spu_RenderSubpictures, just pass it along (or do it inside             * spu_RenderSubpictures) */            video_format_t fmt_org = *p_fmt;            fmt_org.i_width =            fmt_org.i_visible_width = i_source_video_width;            fmt_org.i_height =            fmt_org.i_visible_height = i_source_video_height;            p_subpic->pf_update_regions( &fmt_org, p_spu, p_subpic, mdate() );        }        /* */        p_region = p_subpic->p_region;        if( !p_region )            continue;        /* Create the blending module */        if( !p_spu->p_blend )            SpuRenderCreateBlend( p_spu, p_fmt->i_chroma, p_fmt->i_aspect );        /* Load the text rendering module; it is possible there is a         * text region somewhere in the subpicture other than the first         * element in the region list, so just load it anyway as we'll         * probably want it sooner or later. */        if( !p_spu->p_text )            SpuRenderCreateAndLoadText( p_spu, p_fmt->i_width, p_fmt->i_height );        if( p_spu->p_text )        {            subpicture_region_t *p_text_region = p_subpic->p_region;            /* Only overwrite the size fields if the region is still in             * pre-rendered TEXT format. We have to traverse the subregion             * list because if more than one subregion is present, the text             * region isn't guarentteed to be the first in the list, and             * only text regions use this flag. All of this effort assists             * with the rescaling of text that has been rendered at native             * resolution, rather than video resolution.             */            while( p_text_region &&                   p_text_region->fmt.i_chroma != VLC_FOURCC('T','E','X','T') )            {                p_text_region = p_text_region->p_next;            }            if( p_text_region &&                ( ( p_text_region->i_align & SUBPICTURE_RENDERED ) == 0 ) )            {                if( p_subpic->i_original_picture_height > 0 &&                    p_subpic->i_original_picture_width  > 0 )                {                    p_spu->p_text->fmt_out.video.i_width =                    p_spu->p_text->fmt_out.video.i_visible_width =                        p_subpic->i_original_picture_width;                    p_spu->p_text->fmt_out.video.i_height =                    p_spu->p_text->fmt_out.video.i_visible_height =                        p_subpic->i_original_picture_height;                }                else                {                    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;                }            }            /* XXX for text:             *  scale[] allows to pass from rendered size (by text module) to video output size */            pi_scale_width[SCALE_TEXT] = p_fmt->i_width * 1000 /                                          p_spu->p_text->fmt_out.video.i_width;            pi_scale_height[SCALE_TEXT]= p_fmt->i_height * 1000 /                                          p_spu->p_text->fmt_out.video.i_height;        }        else        {            /* Just set a value to avoid using invalid memory while looping over the array */            pi_scale_width[SCALE_TEXT] =            pi_scale_height[SCALE_TEXT]= 1000;        }        /* XXX for default:         *  scale[] allows to pass from native (either video or original) size to output size */        if( p_subpic->i_original_picture_height > 0 &&            p_subpic->i_original_picture_width  > 0 )        {            pi_scale_width[SCALE_DEFAULT]  = p_fmt->i_width  * 1000 / p_subpic->i_original_picture_width;            pi_scale_height[SCALE_DEFAULT] = p_fmt->i_height * 1000 / p_subpic->i_original_picture_height;        }        else        {            pi_scale_width[ SCALE_DEFAULT ]  = i_scale_width_orig;            pi_scale_height[ SCALE_DEFAULT ] = i_scale_height_orig;        }        for( k = 0; k < SCALE_SIZE ; k++ )        {            /* Case of both width and height being specified has been dealt             * with above by instead rendering to an output pane of the             * explicit dimensions specified - we don't need to scale it.             */            if( p_subpic->i_original_picture_height > 0 &&                p_subpic->i_original_picture_width <= 0 )            {                pi_scale_height[ k ] = pi_scale_height[ k ] * i_source_video_height /                                 p_subpic->i_original_picture_height;                pi_scale_width[ k ]  = pi_scale_width[ k ]  * i_source_video_height /                                 p_subpic->i_original_picture_height;            }        }        /* Set default subpicture aspect ratio */        if( !p_region->fmt.i_sar_num || !p_region->fmt.i_sar_den )        {            if( p_region->fmt.i_aspect != 0 )            {                p_region->fmt.i_sar_den = p_region->fmt.i_aspect;                p_region->fmt.i_sar_num = VOUT_ASPECT_FACTOR;            }            else            {                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->fmt.i_sar_num * p_fmt->i_sar_den ) !=

⌨️ 快捷键说明

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