Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-gpu
Commits
959bd283
Commit
959bd283
authored
Feb 01, 2005
by
Olivier Aubert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
svg.c: ported the code for vlc 0.8.1 (as a video filter)
parent
827129dd
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
185 additions
and
171 deletions
+185
-171
modules/misc/svg.c
modules/misc/svg.c
+185
-171
No files found.
modules/misc/svg.c
View file @
959bd283
...
...
@@ -33,6 +33,9 @@
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include "osd.h"
#include "vlc_block.h"
#include "vlc_filter.h"
#include <librsvg-2/librsvg/rsvg.h>
...
...
@@ -41,17 +44,7 @@
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
void
Render
(
vout_thread_t
*
,
picture_t
*
,
const
subpicture_t
*
);
static
subpicture_t
*
AddText
(
vout_thread_t
*
p_vout
,
int
i_channel
,
char
*
psz_string
,
text_style_t
*
p_style
,
int
i_flags
,
int
i_hmargin
,
int
i_vmargin
,
mtime_t
i_start
,
mtime_t
i_stop
);
static
byte_t
*
svg_GetTemplate
();
static
void
svg_SizeCallback
(
int
*
width
,
int
*
height
,
gpointer
data
);
static
void
svg_RenderPicture
(
vout_thread_t
*
p_vout
,
subpicture_sys_t
*
p_string
);
static
void
FreeString
(
subpicture_t
*
);
static
subpicture_t
*
RenderText
(
filter_t
*
,
block_t
*
);
/*****************************************************************************
* Module descriptor
...
...
@@ -61,9 +54,7 @@ static void FreeString( subpicture_t * );
#define TEMPLATE_LONGTEXT N_( "Location of a file holding a SVG template for automatic string conversion" )
vlc_module_begin
();
set_category
(
CAT_VIDEO
);
set_subcategory
(
SUBCAT_VIDEO_TEXT
);
set_capability
(
"text renderer"
,
100
);
set_capability
(
"text renderer"
,
101
);
add_shortcut
(
"svg"
);
add_string
(
"svg-template-file"
,
""
,
NULL
,
TEMPLATE_TEXT
,
TEMPLATE_LONGTEXT
,
VLC_TRUE
);
set_callbacks
(
Create
,
Destroy
);
...
...
@@ -72,7 +63,7 @@ vlc_module_end();
/**
Describes a SVG string to be displayed on the video
*/
struct
subpicture_sys
_t
typedef
struct
subpicture_data
_t
{
int
i_width
;
int
i_height
;
...
...
@@ -81,18 +72,28 @@ struct subpicture_sys_t
byte_t
*
psz_text
;
/* The rendered SVG, as a GdkPixbuf */
GdkPixbuf
*
p_rendition
;
};
}
subpicture_data_t
;
static
void
Render
(
filter_t
*
,
subpicture_t
*
,
subpicture_data_t
*
);
static
byte_t
*
svg_GetTemplate
();
static
void
svg_SizeCallback
(
int
*
width
,
int
*
height
,
gpointer
data
);
static
void
svg_RenderPicture
(
filter_t
*
p_filter
,
subpicture_data_t
*
p_string
);
static
void
FreeString
(
subpicture_data_t
*
);
/*****************************************************************************
*
vout
_sys_t: svg local data
*
filter
_sys_t: svg local data
*****************************************************************************
* This structure is part of the
video output
thread descriptor.
* This structure is part of the
filter
thread descriptor.
* It describes the svg specific properties of an output thread.
*****************************************************************************/
struct
text_render
er_sys_t
struct
filt
er_sys_t
{
/* The SVG template used to convert strings */
byte_t
*
psz_template
;
/* Default size for rendering. Initialized to the output size. */
int
i_width
;
int
i_height
;
vlc_mutex_t
*
lock
;
};
...
...
@@ -103,36 +104,45 @@ struct text_renderer_sys_t
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
p_this
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
;
/* Allocate structure */
p_
vout
->
p_text_renderer_data
=
malloc
(
sizeof
(
text_render
er_sys_t
)
);
if
(
p_vout
->
p_text_renderer_data
==
NULL
)
p_
sys
=
malloc
(
sizeof
(
filt
er_sys_t
)
);
if
(
!
p_sys
)
{
msg_Err
(
p_
vout
,
"Out of memory"
);
msg_Err
(
p_
filter
,
"Out of memory"
);
return
VLC_ENOMEM
;
}
p_vout
->
pf_add_string
=
AddText
;
/* Initialize psz_template */
p_
vout
->
p_text_renderer_data
->
psz_template
=
svg_GetTemplate
(
p_this
);
if
(
!
p_
vout
->
p_text_renderer_data
->
psz_template
)
p_
sys
->
psz_template
=
svg_GetTemplate
(
p_this
);
if
(
!
p_
sys
->
psz_template
)
{
msg_Err
(
p_
vout
,
"Out of memory"
);
msg_Err
(
p_
filter
,
"Out of memory"
);
return
VLC_ENOMEM
;
}
p_sys
->
i_width
=
p_filter
->
fmt_out
.
video
.
i_width
;
p_sys
->
i_height
=
p_filter
->
fmt_out
.
video
.
i_height
;
p_filter
->
pf_render_string
=
RenderText
;
p_filter
->
p_sys
=
p_sys
;
/* MUST call this before any RSVG funcs */
g_type_init
();
return
VLC_SUCCESS
;
}
static
byte_t
*
svg_GetTemplate
(
vlc_object_t
*
p_this
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
char
*
psz_filename
;
char
*
psz_template
;
FILE
*
file
;
psz_filename
=
config_GetPsz
(
p_
vout
,
"svg-template-file"
);
psz_filename
=
config_GetPsz
(
p_
filter
,
"svg-template-file"
);
if
(
!
psz_filename
||
psz_filename
[
0
]
==
0
)
{
/* No filename. Use a default value. */
...
...
@@ -161,14 +171,15 @@ static byte_t *svg_GetTemplate( vlc_object_t *p_this )
}
else
{
fprintf
(
stderr
,
"Reading %ld bytes from
%s
\n
"
,
(
long
)
s
.
st_size
,
psz_filename
);
msg_Dbg
(
p_this
,
"Reading %ld bytes from template
%s
\n
"
,
(
long
)
s
.
st_size
,
psz_filename
);
psz_template
=
malloc
(
s
.
st_size
+
42
);
if
(
!
psz_template
)
{
msg_Err
(
p_
vout
,
"Out of memory"
);
msg_Err
(
p_
filter
,
"Out of memory"
);
return
NULL
;
}
memset
(
psz_template
,
0
,
s
.
st_size
+
1
);
fread
(
psz_template
,
s
.
st_size
,
1
,
file
);
fclose
(
file
);
}
...
...
@@ -194,41 +205,70 @@ static byte_t *svg_GetTemplate( vlc_object_t *p_this )
*****************************************************************************/
static
void
Destroy
(
vlc_object_t
*
p_this
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
free
(
p_vout
->
p_text_renderer_data
->
psz_template
);
free
(
p_vout
->
p_text_renderer_data
);
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
free
(
p_sys
->
psz_template
);
free
(
p_sys
);
}
/*****************************************************************************
* Render: render SVG in picture
*****************************************************************************
* This function merges the previously rendered SVG subpicture into a picture
*****************************************************************************/
static
void
Render
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
,
const
subpicture_t
*
p_subpic
)
static
void
Render
(
filter_t
*
p_filter
,
subpicture_t
*
p_spu
,
subpicture_data_t
*
p_string
)
{
subpicture_sys_t
*
p_string
=
p_subpic
->
p_sys
;
guchar
*
pixels_in
=
NULL
;
guchar
*
pixels_out
=
NULL
;
int
rowstride_in
,
rowstride_out
;
int
channels_in
,
channels_out
;
int
x
,
y
;
int
i_width
,
i_height
;
video_format_t
fmt
;
uint8_t
*
p_y
,
*
p_u
,
*
p_v
,
*
p_a
;
int
x
,
y
,
i_pitch
,
i_u_pitch
;
guchar
*
pixels_in
=
NULL
;
int
rowstride_in
;
int
channels_in
;
int
alpha
;
picture_t
*
p_pic
;
if
(
p_string
->
p_rendition
==
NULL
)
{
/* Something changed ( presumably the dimensions ). Get the new
dimensions and update the pixbuf */
p_string
->
i_width
=
p_vout
->
output
.
i_width
;
p_string
->
i_height
=
p_vout
->
output
.
i_height
;
svg_RenderPicture
(
p_vout
,
p_string
);
svg_RenderPicture
(
p_filter
,
p_string
);
}
i_width
=
gdk_pixbuf_get_width
(
p_string
->
p_rendition
);
i_height
=
gdk_pixbuf_get_height
(
p_string
->
p_rendition
);
/* This rendering code is in no way optimized. If someone has some
time to lose to make it work faster, please do.
*/
/* Create a new subpicture region */
memset
(
&
fmt
,
0
,
sizeof
(
video_format_t
)
);
fmt
.
i_chroma
=
VLC_FOURCC
(
'Y'
,
'U'
,
'V'
,
'A'
);
fmt
.
i_aspect
=
VOUT_ASPECT_FACTOR
;
fmt
.
i_width
=
fmt
.
i_visible_width
=
i_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
=
i_height
;
fmt
.
i_x_offset
=
fmt
.
i_y_offset
=
0
;
p_spu
->
p_region
=
p_spu
->
pf_create_region
(
VLC_OBJECT
(
p_filter
),
&
fmt
);
if
(
!
p_spu
->
p_region
)
{
msg_Err
(
p_filter
,
"cannot allocate SPU region"
);
return
;
}
p_spu
->
p_region
->
i_x
=
p_spu
->
p_region
->
i_y
=
0
;
p_y
=
p_spu
->
p_region
->
picture
.
Y_PIXELS
;
p_u
=
p_spu
->
p_region
->
picture
.
U_PIXELS
;
p_v
=
p_spu
->
p_region
->
picture
.
V_PIXELS
;
p_a
=
p_spu
->
p_region
->
picture
.
A_PIXELS
;
i_pitch
=
p_spu
->
p_region
->
picture
.
Y_PITCH
;
i_u_pitch
=
p_spu
->
p_region
->
picture
.
U_PITCH
;
/* Initialize the region pixels (only the alpha will be changed later) */
memset
(
p_y
,
0x00
,
i_pitch
*
p_spu
->
p_region
->
fmt
.
i_height
);
memset
(
p_u
,
0x80
,
i_u_pitch
*
p_spu
->
p_region
->
fmt
.
i_height
);
memset
(
p_v
,
0x80
,
i_u_pitch
*
p_spu
->
p_region
->
fmt
.
i_height
);
/* FIXME: The alpha value is not taken into account. */
p_pic
=
&
(
p_spu
->
p_region
->
picture
);
/* Copy the data */
/* This rendering code is in no way optimized. If someone has some time to
make it work faster or better, please do.
*/
/*
p_pixbuf->get_rowstride() is the number of bytes in a line.
...
...
@@ -245,107 +285,78 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic,
*/
pixels_in
=
gdk_pixbuf_get_pixels
(
p_string
->
p_rendition
);
pixels_out
=
p_pic
->
p
->
p_pixels
;
rowstride_in
=
gdk_pixbuf_get_rowstride
(
p_string
->
p_rendition
);
rowstride_out
=
p_pic
->
p
->
i_pitch
;
channels_in
=
gdk_pixbuf_get_n_channels
(
p_string
->
p_rendition
);
channels_out
=
p_pic
->
p
->
i_pixel_pitch
;
alpha
=
gdk_pixbuf_get_has_alpha
(
p_string
->
p_rendition
);
#define INDEX_IN( x, y ) ( y * rowstride_in + x * channels_in )
#define INDEX_OUT( x, y ) ( y * rowstride_out + x * channels_out )
#define UV_INDEX_OUT( x, y ) ( y * p_pic->p[U_PLANE].i_pitch / 2 + x * p_pic->p[U_PLANE].i_pixel_pitch / 2 )
i_width
=
gdk_pixbuf_get_width
(
p_string
->
p_rendition
);
i_height
=
gdk_pixbuf_get_height
(
p_string
->
p_rendition
);
/*
This crashes the plugin (if !alpha). As there is always an alpha value,
it does not matter for the moment :
switch
(
p_vout
->
output
.
i_chroma
)
if( !alpha )
memset( p_a, 0xFF, i_pitch * p_spu->p_region->fmt.i_height );
*/
#define INDEX_IN( x, y ) ( y * rowstride_in + x * channels_in )
#define INDEX_OUT( x, y ) ( y * i_pitch + x * p_pic->p[Y_PLANE].i_pixel_pitch )
#define UV_INDEX_OUT( x, y ) ( ( y >> 1 ) * i_u_pitch + ( x >> 1) * p_pic->p[U_PLANE].i_pixel_pitch )
for
(
y
=
0
;
y
<
i_height
;
y
++
)
{
/* I420 target, no scaling */
case
VLC_FOURCC
(
'I'
,
'4'
,
'2'
,
'0'
):
case
VLC_FOURCC
(
'I'
,
'Y'
,
'U'
,
'V'
):
case
VLC_FOURCC
(
'Y'
,
'V'
,
'1'
,
'2'
):
for
(
y
=
0
;
y
<
i_height
;
y
++
)
for
(
x
=
0
;
x
<
i_width
;
x
++
)
{
for
(
x
=
0
;
x
<
i_width
;
x
++
)
{
guchar
*
p_in
;
int
i_out
;
int
i_uv_out
;
p_in
=
&
pixels_in
[
INDEX_IN
(
x
,
y
)];
guchar
*
p_in
;
int
i_out
;
int
i_uv_out
;
p_in
=
&
pixels_in
[
INDEX_IN
(
x
,
y
)];
#define R( pixel ) *pixel
#define G( pixel ) *( pixel+1 )
#define B( pixel ) *( pixel+2 )
#define ALPHA( pixel ) *( pixel+3 )
/* From http://www.geocrawler.com/archives/3/8263/2001/6/0/6020594/ :
Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
U = -0.1687 * r - 0.3313 * g + 0.5 * b + 128
V = 0.5 * r - 0.4187 * g - 0.0813 * b + 128
*/
if
(
(
alpha
&&
ALPHA
(
p_in
)
>
10
)
||
(
!
alpha
))
{
i_out
=
INDEX_OUT
(
x
,
y
);
p_pic
->
p
[
Y_PLANE
].
p_pixels
[
i_out
]
=
.
299
*
R
(
p_in
)
+
.
587
*
G
(
p_in
)
+
.
114
*
B
(
p_in
);
if
(
(
x
%
2
==
0
)
&&
(
y
%
2
==
0
)
)
{
i_uv_out
=
UV_INDEX_OUT
(
x
,
y
);
p_pic
->
p
[
U_PLANE
].
p_pixels
[
i_uv_out
]
=
-
.
1687
*
R
(
p_in
)
-
.
3313
*
G
(
p_in
)
+
.
5
*
B
(
p_in
)
+
128
;
p_pic
->
p
[
V_PLANE
].
p_pixels
[
i_uv_out
]
=
.
5
*
R
(
p_in
)
-
.
4187
*
G
(
p_in
)
-
.
0813
*
B
(
p_in
)
+
128
;
}
/* From http://www.geocrawler.com/archives/3/8263/2001/6/0/6020594/ :
Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
U = -0.1687 * r - 0.3313 * g + 0.5 * b + 128
V = 0.5 * r - 0.4187 * g - 0.0813 * b + 128
*/
if
(
alpha
)
{
i_out
=
INDEX_OUT
(
x
,
y
);
p_pic
->
Y_PIXELS
[
i_out
]
=
.
299
*
R
(
p_in
)
+
.
587
*
G
(
p_in
)
+
.
114
*
B
(
p_in
);
p_pic
->
A_PIXELS
[
i_out
]
=
ALPHA
(
p_in
);
if
(
(
x
%
2
==
0
)
&&
(
y
%
2
==
0
)
)
{
i_uv_out
=
UV_INDEX_OUT
(
x
,
y
);
p_pic
->
U_PIXELS
[
i_uv_out
]
=
-
.
1687
*
R
(
p_in
)
-
.
3313
*
G
(
p_in
)
+
.
5
*
B
(
p_in
)
+
128
;
p_pic
->
V_PIXELS
[
i_uv_out
]
=
.
5
*
R
(
p_in
)
-
.
4187
*
G
(
p_in
)
-
.
0813
*
B
(
p_in
)
+
128
;
}
}
}
break
;
/* RV32 target, scaling */
case
VLC_FOURCC
(
'R'
,
'V'
,
'2'
,
'4'
):
case
VLC_FOURCC
(
'R'
,
'V'
,
'3'
,
'2'
):
for
(
y
=
0
;
y
<
i_height
;
y
++
)
{
for
(
x
=
0
;
x
<
i_width
;
x
++
)
{
guchar
*
p_in
;
guchar
*
p_out
;
p_in
=
&
pixels_in
[
INDEX_IN
(
x
,
y
)];
p_out
=
&
pixels_out
[
INDEX_OUT
(
x
,
y
)];
*
p_out
=
*
p_in
;
*
(
p_out
+
1
)
=
*
(
p_in
+
1
);
*
(
p_out
+
2
)
=
*
(
p_in
+
2
);
}
}
break
;
default:
msg_Err
(
p_vout
,
"unknown chroma, can't render SVG"
);
break
;
}
}
static
void
svg_SizeCallback
(
int
*
width
,
int
*
height
,
gpointer
data
)
{
subpicture_
sys
_t
*
p_string
=
data
;
subpicture_
data
_t
*
p_string
=
data
;
*
width
=
p_string
->
i_width
;
*
height
=
p_string
->
i_height
;
return
;
}
static
void
svg_RenderPicture
(
vout_thread_t
*
p_vout
,
subpicture_
sys
_t
*
p_string
)
static
void
svg_RenderPicture
(
filter_t
*
p_filter
,
subpicture_
data
_t
*
p_string
)
{
/* Render the SVG string p_string->psz_text into a new picture_t
p_string->p_rendition with dimensions ( ->i_width, ->i_height ) */
RsvgHandle
*
p_handle
;
GError
*
error
;
GError
*
error
=
NULL
;
p_handle
=
rsvg_handle_new
();
...
...
@@ -354,6 +365,11 @@ static void svg_RenderPicture( vout_thread_t *p_vout,
rsvg_handle_write
(
p_handle
,
p_string
->
psz_text
,
strlen
(
p_string
->
psz_text
)
+
1
,
&
error
);
if
(
error
!=
NULL
)
{
msg_Err
(
p_filter
,
"Error in handle_write: %s
\n
"
,
error
->
message
);
return
;
}
rsvg_handle_close
(
p_handle
,
&
error
);
p_string
->
p_rendition
=
rsvg_handle_get_pixbuf
(
p_handle
);
...
...
@@ -361,89 +377,87 @@ static void svg_RenderPicture( vout_thread_t *p_vout,
}
/**
* This function receives a SVG string and creates a subpicture for it.
* It is used as pf_add_string callback in the vout method by this module.
*/
static
subpicture_t
*
AddText
(
vout_thread_t
*
p_vout
,
int
i_channel
,
char
*
psz_string
,
text_style_t
*
p_style
,
int
i_flags
,
int
i_hmargin
,
int
i_vmargin
,
mtime_t
i_start
,
mtime_t
i_stop
)
static
subpicture_t
*
RenderText
(
filter_t
*
p_filter
,
block_t
*
p_block
)
{
subpicture_sys_t
*
p_string
;
subpicture_t
*
p_subpic
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
subpicture_t
*
p_subpic
=
NULL
;
subpicture_data_t
*
p_string
=
NULL
;
char
*
psz_string
;
msg_Dbg
(
p_vout
,
"adding string
\"
%s
\"
start_date "
I64Fd
" end_date"
I64Fd
,
psz_string
,
i_start
,
i_stop
);
/* Sanity check */
if
(
!
p_block
)
return
NULL
;
psz_string
=
p_block
->
p_buffer
;
if
(
!
psz_string
||
!*
psz_string
)
return
NULL
;
/* Create and initialize a subpicture */
p_subpic
=
vout_CreateSubPicture
(
p_vout
,
i_channel
,
GRAPH_CONTENT
,
MEMORY_SUBPICTURE
);
if
(
p_subpic
==
NULL
)
{
return
NULL
;
}
p_subpic
=
p_filter
->
pf_sub_buffer_new
(
p_filter
);
if
(
!
p_subpic
)
return
NULL
;
p_subpic
->
pf_render
=
Render
;
p_subpic
->
pf_destroy
=
FreeString
;
p_subpic
->
i_start
=
i_start
;
p_subpic
->
i_stop
=
i_stop
;
if
(
i_stop
==
0
)
{
p_subpic
->
b_ephemer
=
VLC_TRUE
;
}
else
{
p_subpic
->
b_ephemer
=
VLC_FALSE
;
}
p_subpic
->
i_start
=
p_block
->
i_pts
;
p_subpic
->
i_stop
=
p_block
->
i_pts
+
p_block
->
i_length
;
/* Always replace rendered text when another is displayed */
p_subpic
->
b_ephemer
=
VLC_TRUE
;
p_subpic
->
b_absolute
=
VLC_FALSE
;
// msg_Dbg( p_filter, "adding string \"%s\" start_date "I64Fd
/* Create and initialize private data for the subpicture */
p_string
=
malloc
(
sizeof
(
subpicture_sys_t
)
);
if
(
p_string
==
NULL
)
p_string
=
malloc
(
sizeof
(
subpicture_data_t
)
);
if
(
!
p_string
)
{
vout_DestroySubPicture
(
p_vout
,
p_subpic
);
msg_Err
(
p_filter
,
"Out of memory"
);
p_filter
->
pf_sub_buffer_del
(
p_filter
,
p_subpic
);
return
NULL
;
}
p_subpic
->
p_sys
=
p_string
;
/* Check if the data is SVG or pure text. In the latter case,
convert the text to SVG. FIXME: find a better test */
if
(
strstr
(
psz_string
,
"<svg"
))
{
/* Data is SVG: duplicate */
p_string
->
psz_text
=
strdup
(
psz_string
);
if
(
!
p_string
->
psz_text
)
{
msg_Err
(
p_filter
,
"Out of memory"
);
p_filter
->
pf_sub_buffer_del
(
p_filter
,
p_subpic
);
free
(
p_string
);
return
NULL
;
}
}
else
{
/* Data is text. Convert to SVG */
int
length
;
byte_t
*
psz_template
=
p_
vout
->
p_text_renderer_data
->
psz_template
;
byte_t
*
psz_template
=
p_
sys
->
psz_template
;
length
=
strlen
(
psz_string
)
+
strlen
(
psz_template
)
+
42
;
p_string
->
psz_text
=
malloc
(
length
+
1
);
if
(
p_string
->
psz_text
==
NULL
)
if
(
!
p_string
->
psz_text
)
{
msg_Err
(
p_filter
,
"Out of memory"
);
p_filter
->
pf_sub_buffer_del
(
p_filter
,
p_subpic
);
free
(
p_string
);
return
NULL
;
}
memset
(
p_string
->
psz_text
,
0
,
length
+
1
);
snprintf
(
p_string
->
psz_text
,
length
,
psz_template
,
psz_string
);
}
p_string
->
i_width
=
p_vout
->
output
.
i_width
;
p_string
->
i_height
=
p_vout
->
output
.
i_height
;
p_string
->
i_chroma
=
p_vout
->
output
.
i_chroma
;
p_string
->
i_width
=
p_sys
->
i_width
;
p_string
->
i_height
=
p_sys
->
i_height
;
p_string
->
i_chroma
=
VLC_FOURCC
(
'Y'
,
'U'
,
'V'
,
'A'
);
/* Render the SVG.
The input data is stored in the p_string structure,
and the function updates the p_rendition attribute. */
svg_RenderPicture
(
p_vout
,
p_string
);
svg_RenderPicture
(
p_filter
,
p_string
);
Render
(
p_filter
,
p_subpic
,
p_string
);
FreeString
(
p_string
);
block_Release
(
p_block
);
vout_DisplaySubPicture
(
p_vout
,
p_subpic
);
return
p_subpic
;
}
static
void
FreeString
(
subpicture_
t
*
p_subpic
)
static
void
FreeString
(
subpicture_
data_t
*
p_string
)
{
subpicture_sys_t
*
p_string
=
p_subpic
->
p_sys
;
free
(
p_string
->
psz_text
);
free
(
p_string
->
p_rendition
);
free
(
p_string
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment