Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
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 @@
...
@@ -33,6 +33,9 @@
#include <vlc/vlc.h>
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/vout.h>
#include "osd.h"
#include "vlc_block.h"
#include "vlc_filter.h"
#include <librsvg-2/librsvg/rsvg.h>
#include <librsvg-2/librsvg/rsvg.h>
...
@@ -41,17 +44,7 @@
...
@@ -41,17 +44,7 @@
*****************************************************************************/
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
);
static
int
Create
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
void
Render
(
vout_thread_t
*
,
picture_t
*
,
static
subpicture_t
*
RenderText
(
filter_t
*
,
block_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
*
);
/*****************************************************************************
/*****************************************************************************
* Module descriptor
* Module descriptor
...
@@ -61,9 +54,7 @@ static void FreeString( subpicture_t * );
...
@@ -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" )
#define TEMPLATE_LONGTEXT N_( "Location of a file holding a SVG template for automatic string conversion" )
vlc_module_begin
();
vlc_module_begin
();
set_category
(
CAT_VIDEO
);
set_capability
(
"text renderer"
,
101
);
set_subcategory
(
SUBCAT_VIDEO_TEXT
);
set_capability
(
"text renderer"
,
100
);
add_shortcut
(
"svg"
);
add_shortcut
(
"svg"
);
add_string
(
"svg-template-file"
,
""
,
NULL
,
TEMPLATE_TEXT
,
TEMPLATE_LONGTEXT
,
VLC_TRUE
);
add_string
(
"svg-template-file"
,
""
,
NULL
,
TEMPLATE_TEXT
,
TEMPLATE_LONGTEXT
,
VLC_TRUE
);
set_callbacks
(
Create
,
Destroy
);
set_callbacks
(
Create
,
Destroy
);
...
@@ -72,7 +63,7 @@ vlc_module_end();
...
@@ -72,7 +63,7 @@ vlc_module_end();
/**
/**
Describes a SVG string to be displayed on the video
Describes a SVG string to be displayed on the video
*/
*/
struct
subpicture_sys
_t
typedef
struct
subpicture_data
_t
{
{
int
i_width
;
int
i_width
;
int
i_height
;
int
i_height
;
...
@@ -81,18 +72,28 @@ struct subpicture_sys_t
...
@@ -81,18 +72,28 @@ struct subpicture_sys_t
byte_t
*
psz_text
;
byte_t
*
psz_text
;
/* The rendered SVG, as a GdkPixbuf */
/* The rendered SVG, as a GdkPixbuf */
GdkPixbuf
*
p_rendition
;
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.
* 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 */
/* The SVG template used to convert strings */
byte_t
*
psz_template
;
byte_t
*
psz_template
;
/* Default size for rendering. Initialized to the output size. */
int
i_width
;
int
i_height
;
vlc_mutex_t
*
lock
;
vlc_mutex_t
*
lock
;
};
};
...
@@ -103,36 +104,45 @@ struct text_renderer_sys_t
...
@@ -103,36 +104,45 @@ struct text_renderer_sys_t
*****************************************************************************/
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
p_this
)
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 */
/* Allocate structure */
p_
vout
->
p_text_renderer_data
=
malloc
(
sizeof
(
text_render
er_sys_t
)
);
p_
sys
=
malloc
(
sizeof
(
filt
er_sys_t
)
);
if
(
p_vout
->
p_text_renderer_data
==
NULL
)
if
(
!
p_sys
)
{
{
msg_Err
(
p_
vout
,
"Out of memory"
);
msg_Err
(
p_
filter
,
"Out of memory"
);
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
}
}
p_vout
->
pf_add_string
=
AddText
;
/* Initialize psz_template */
/* Initialize psz_template */
p_
vout
->
p_text_renderer_data
->
psz_template
=
svg_GetTemplate
(
p_this
);
p_
sys
->
psz_template
=
svg_GetTemplate
(
p_this
);
if
(
!
p_
vout
->
p_text_renderer_data
->
psz_template
)
if
(
!
p_
sys
->
psz_template
)
{
{
msg_Err
(
p_
vout
,
"Out of memory"
);
msg_Err
(
p_
filter
,
"Out of memory"
);
return
VLC_ENOMEM
;
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
;
return
VLC_SUCCESS
;
}
}
static
byte_t
*
svg_GetTemplate
(
vlc_object_t
*
p_this
)
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_filename
;
char
*
psz_template
;
char
*
psz_template
;
FILE
*
file
;
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
)
if
(
!
psz_filename
||
psz_filename
[
0
]
==
0
)
{
{
/* No filename. Use a default value. */
/* No filename. Use a default value. */
...
@@ -161,14 +171,15 @@ static byte_t *svg_GetTemplate( vlc_object_t *p_this )
...
@@ -161,14 +171,15 @@ static byte_t *svg_GetTemplate( vlc_object_t *p_this )
}
}
else
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
);
psz_template
=
malloc
(
s
.
st_size
+
42
);
if
(
!
psz_template
)
if
(
!
psz_template
)
{
{
msg_Err
(
p_
vout
,
"Out of memory"
);
msg_Err
(
p_
filter
,
"Out of memory"
);
return
NULL
;
return
NULL
;
}
}
memset
(
psz_template
,
0
,
s
.
st_size
+
1
);
fread
(
psz_template
,
s
.
st_size
,
1
,
file
);
fread
(
psz_template
,
s
.
st_size
,
1
,
file
);
fclose
(
file
);
fclose
(
file
);
}
}
...
@@ -194,41 +205,70 @@ static byte_t *svg_GetTemplate( vlc_object_t *p_this )
...
@@ -194,41 +205,70 @@ static byte_t *svg_GetTemplate( vlc_object_t *p_this )
*****************************************************************************/
*****************************************************************************/
static
void
Destroy
(
vlc_object_t
*
p_this
)
static
void
Destroy
(
vlc_object_t
*
p_this
)
{
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
free
(
p_vout
->
p_text_renderer_data
->
psz_template
);
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
free
(
p_vout
->
p_text_renderer_data
);
free
(
p_sys
->
psz_template
);
free
(
p_sys
);
}
}
/*****************************************************************************
/*****************************************************************************
* Render: render SVG in picture
* 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
,
static
void
Render
(
filter_t
*
p_filter
,
subpicture_t
*
p_spu
,
const
subpicture_t
*
p_subpic
)
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
;
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
;
int
alpha
;
picture_t
*
p_pic
;
if
(
p_string
->
p_rendition
==
NULL
)
{
if
(
p_string
->
p_rendition
==
NULL
)
{
/* Something changed ( presumably the dimensions ). Get the new
svg_RenderPicture
(
p_filter
,
p_string
);
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
);
}
}
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
/* Create a new subpicture region */
time to lose to make it work faster, please do.
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.
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,
...
@@ -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_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_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_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
);
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 )
This crashes the plugin (if !alpha). As there is always an alpha value,
#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 )
it does not matter for the moment :
i_width
=
gdk_pixbuf_get_width
(
p_string
->
p_rendition
);
i_height
=
gdk_pixbuf_get_height
(
p_string
->
p_rendition
);
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 */
for
(
x
=
0
;
x
<
i_width
;
x
++
)
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
++
)
guchar
*
p_in
;
{
int
i_out
;
guchar
*
p_in
;
int
i_uv_out
;
int
i_out
;
int
i_uv_out
;
p_in
=
&
pixels_in
[
INDEX_IN
(
x
,
y
)];
p_in
=
&
pixels_in
[
INDEX_IN
(
x
,
y
)];
#define R( pixel ) *pixel
#define R( pixel ) *pixel
#define G( pixel ) *( pixel+1 )
#define G( pixel ) *( pixel+1 )
#define B( pixel ) *( pixel+2 )
#define B( pixel ) *( pixel+2 )
#define ALPHA( pixel ) *( pixel+3 )
#define ALPHA( pixel ) *( pixel+3 )
/* From http://www.geocrawler.com/archives/3/8263/2001/6/0/6020594/ :
/* From http://www.geocrawler.com/archives/3/8263/2001/6/0/6020594/ :
Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
U = -0.1687 * r - 0.3313 * g + 0.5 * b + 128
U = -0.1687 * r - 0.3313 * g + 0.5 * b + 128
V = 0.5 * r - 0.4187 * g - 0.0813 * b + 128
V = 0.5 * r - 0.4187 * g - 0.0813 * b + 128
*/
*/
if
(
(
alpha
&&
ALPHA
(
p_in
)
>
10
)
||
(
!
alpha
))
{
if
(
alpha
)
{
i_out
=
INDEX_OUT
(
x
,
y
);
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
);
p_pic
->
Y_PIXELS
[
i_out
]
=
.
299
*
R
(
p_in
)
+
.
587
*
G
(
p_in
)
+
.
114
*
B
(
p_in
);
if
(
(
x
%
2
==
0
)
&&
(
y
%
2
==
0
)
)
{
p_pic
->
A_PIXELS
[
i_out
]
=
ALPHA
(
p_in
);
i_uv_out
=
UV_INDEX_OUT
(
x
,
y
);
if
(
(
x
%
2
==
0
)
&&
(
y
%
2
==
0
)
)
{
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
;
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
)
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
;
*
width
=
p_string
->
i_width
;
*
height
=
p_string
->
i_height
;
*
height
=
p_string
->
i_height
;
return
;
return
;
}
}
static
void
svg_RenderPicture
(
vout_thread_t
*
p_vout
,
static
void
svg_RenderPicture
(
filter_t
*
p_filter
,
subpicture_
sys
_t
*
p_string
)
subpicture_
data
_t
*
p_string
)
{
{
/* Render the SVG string p_string->psz_text into a new picture_t
/* Render the SVG string p_string->psz_text into a new picture_t
p_string->p_rendition with dimensions ( ->i_width, ->i_height ) */
p_string->p_rendition with dimensions ( ->i_width, ->i_height ) */
RsvgHandle
*
p_handle
;
RsvgHandle
*
p_handle
;
GError
*
error
;
GError
*
error
=
NULL
;
p_handle
=
rsvg_handle_new
();
p_handle
=
rsvg_handle_new
();
...
@@ -354,6 +365,11 @@ static void svg_RenderPicture( vout_thread_t *p_vout,
...
@@ -354,6 +365,11 @@ static void svg_RenderPicture( vout_thread_t *p_vout,
rsvg_handle_write
(
p_handle
,
rsvg_handle_write
(
p_handle
,
p_string
->
psz_text
,
strlen
(
p_string
->
psz_text
)
+
1
,
p_string
->
psz_text
,
strlen
(
p_string
->
psz_text
)
+
1
,
&
error
);
&
error
);
if
(
error
!=
NULL
)
{
msg_Err
(
p_filter
,
"Error in handle_write: %s
\n
"
,
error
->
message
);
return
;
}
rsvg_handle_close
(
p_handle
,
&
error
);
rsvg_handle_close
(
p_handle
,
&
error
);
p_string
->
p_rendition
=
rsvg_handle_get_pixbuf
(
p_handle
);
p_string
->
p_rendition
=
rsvg_handle_get_pixbuf
(
p_handle
);
...
@@ -361,89 +377,87 @@ static void svg_RenderPicture( vout_thread_t *p_vout,
...
@@ -361,89 +377,87 @@ static void svg_RenderPicture( vout_thread_t *p_vout,
}
}
/**
static
subpicture_t
*
RenderText
(
filter_t
*
p_filter
,
block_t
*
p_block
)
* 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
)
{
{
subpicture_sys_t
*
p_string
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
subpicture_t
*
p_subpic
;
subpicture_t
*
p_subpic
=
NULL
;
subpicture_data_t
*
p_string
=
NULL
;
char
*
psz_string
;
msg_Dbg
(
p_vout
,
"adding string
\"
%s
\"
start_date "
I64Fd
/* Sanity check */
" end_date"
I64Fd
,
psz_string
,
i_start
,
i_stop
);
if
(
!
p_block
)
return
NULL
;
psz_string
=
p_block
->
p_buffer
;
if
(
!
psz_string
||
!*
psz_string
)
return
NULL
;
/* Create and initialize a subpicture */
/* Create and initialize a subpicture */
p_subpic
=
vout_CreateSubPicture
(
p_vout
,
i_channel
,
GRAPH_CONTENT
,
p_subpic
=
p_filter
->
pf_sub_buffer_new
(
p_filter
);
MEMORY_SUBPICTURE
);
if
(
!
p_subpic
)
return
NULL
;
if
(
p_subpic
==
NULL
)
{
return
NULL
;
}
p_subpic
->
pf_render
=
Render
;
p_subpic
->
i_start
=
p_block
->
i_pts
;
p_subpic
->
pf_destroy
=
FreeString
;
p_subpic
->
i_stop
=
p_block
->
i_pts
+
p_block
->
i_length
;
p_subpic
->
i_start
=
i_start
;
/* Always replace rendered text when another is displayed */
p_subpic
->
i_stop
=
i_stop
;
p_subpic
->
b_ephemer
=
VLC_TRUE
;
if
(
i_stop
==
0
)
p_subpic
->
b_absolute
=
VLC_FALSE
;
{
p_subpic
->
b_ephemer
=
VLC_TRUE
;
// msg_Dbg( p_filter, "adding string \"%s\" start_date "I64Fd
}
else
{
p_subpic
->
b_ephemer
=
VLC_FALSE
;
}
/* Create and initialize private data for the subpicture */
/* Create and initialize private data for the subpicture */
p_string
=
malloc
(
sizeof
(
subpicture_sys_t
)
);
p_string
=
malloc
(
sizeof
(
subpicture_data_t
)
);
if
(
p_string
==
NULL
)
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
;
return
NULL
;
}
}
p_subpic
->
p_sys
=
p_string
;
/* Check if the data is SVG or pure text. In the latter case,
/* Check if the data is SVG or pure text. In the latter case,
convert the text to SVG. FIXME: find a better test */
convert the text to SVG. FIXME: find a better test */
if
(
strstr
(
psz_string
,
"<svg"
))
if
(
strstr
(
psz_string
,
"<svg"
))
{
{
/* Data is SVG: duplicate */
/* Data is SVG: duplicate */
p_string
->
psz_text
=
strdup
(
psz_string
);
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
else
{
{
/* Data is text. Convert to SVG */
/* Data is text. Convert to SVG */
int
length
;
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
;
length
=
strlen
(
psz_string
)
+
strlen
(
psz_template
)
+
42
;
p_string
->
psz_text
=
malloc
(
length
+
1
);
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
;
return
NULL
;
}
}
memset
(
p_string
->
psz_text
,
0
,
length
+
1
);
snprintf
(
p_string
->
psz_text
,
length
,
psz_template
,
psz_string
);
snprintf
(
p_string
->
psz_text
,
length
,
psz_template
,
psz_string
);
}
}
p_string
->
i_width
=
p_sys
->
i_width
;
p_string
->
i_width
=
p_vout
->
output
.
i_width
;
p_string
->
i_height
=
p_sys
->
i_height
;
p_string
->
i_height
=
p_vout
->
output
.
i_height
;
p_string
->
i_chroma
=
VLC_FOURCC
(
'Y'
,
'U'
,
'V'
,
'A'
);
p_string
->
i_chroma
=
p_vout
->
output
.
i_chroma
;
/* Render the SVG.
/* Render the SVG.
The input data is stored in the p_string structure,
The input data is stored in the p_string structure,
and the function updates the p_rendition attribute. */
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
;
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
->
psz_text
);
free
(
p_string
->
p_rendition
);
free
(
p_string
->
p_rendition
);
free
(
p_string
);
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