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
1ac8441a
Commit
1ac8441a
authored
Apr 09, 2008
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dynamicoverlay'
parents
665cd920
569f294d
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
2560 additions
and
3 deletions
+2560
-3
THANKS
THANKS
+1
-0
configure.ac
configure.ac
+2
-1
include/vlc_vout.h
include/vlc_vout.h
+2
-1
modules/video_filter/Modules.am
modules/video_filter/Modules.am
+1
-0
modules/video_filter/blendbench.c
modules/video_filter/blendbench.c
+251
-0
modules/video_filter/dynamicoverlay/Modules.am
modules/video_filter/dynamicoverlay/Modules.am
+2
-0
modules/video_filter/dynamicoverlay/dynamicoverlay.c
modules/video_filter/dynamicoverlay/dynamicoverlay.c
+421
-0
modules/video_filter/dynamicoverlay/dynamicoverlay.h
modules/video_filter/dynamicoverlay/dynamicoverlay.h
+170
-0
modules/video_filter/dynamicoverlay/dynamicoverlay_buffer.c
modules/video_filter/dynamicoverlay/dynamicoverlay_buffer.c
+160
-0
modules/video_filter/dynamicoverlay/dynamicoverlay_commands.c
...les/video_filter/dynamicoverlay/dynamicoverlay_commands.c
+932
-0
modules/video_filter/dynamicoverlay/dynamicoverlay_list.c
modules/video_filter/dynamicoverlay/dynamicoverlay_list.c
+143
-0
modules/video_filter/dynamicoverlay/dynamicoverlay_queue.c
modules/video_filter/dynamicoverlay/dynamicoverlay_queue.c
+115
-0
modules/video_filter/osdmenu.c
modules/video_filter/osdmenu.c
+1
-0
src/video_output/vout_subpictures.c
src/video_output/vout_subpictures.c
+4
-1
test/dynamicoverlay/Makefile
test/dynamicoverlay/Makefile
+4
-0
test/dynamicoverlay/overlay-test.c
test/dynamicoverlay/overlay-test.c
+351
-0
No files found.
THANKS
View file @
1ac8441a
...
...
@@ -208,6 +208,7 @@ Sebastian Jenny <jenny - sebastian &t gmail - com > - AAC decoding channel order
Sebastien Chaumat <Sebastien.Chaumat at ens-lyon.fr> - YOPY port tests
Sidney Doria <ssdoria qt gmail.com> - Brazilian Portuguese localisation
Simon Damkjær Andersen <simondamkjaer at gmail.com> - playmode icons and the entire Fullscreen Panel design for the OSX GUI (v0.8.6)
Soren Bog <avacore at videolan dot org> - dynamicoverlays
Stefán Freyr Stefánsson <stefan.freyr -at- gmail.com> - Qt4 speed slider
Steve Lhomme <steve dot lhomme at free dot fr> - MSVC fixes and Matroska enhancements
Steve Brown <sbrown at cortland.com> - fix for optional PES size bug
...
...
configure.ac
View file @
1ac8441a
...
...
@@ -1200,7 +1200,7 @@ dnl
VLC_ADD_PLUGINS([dummy logger memcpy])
VLC_ADD_PLUGINS([mpgv mpga m4v m4a h264 vc1 demux_cdg cdg ps pva avi asf mp4 rawdv rawvid nsv real aiff mjpeg demuxdump flacsys tta])
VLC_ADD_PLUGINS([cvdsub svcdsub spudec subsdec subsusf t140 dvbsub cc mpeg_audio lpcm a52 dts cinepak flac])
VLC_ADD_PLUGINS([deinterlace invert adjust transform wave ripple psychedelic gradient motionblur rv32 rotate noise grain extract sharpen seamcarving croppadd])
VLC_ADD_PLUGINS([deinterlace invert adjust transform wave ripple psychedelic gradient motionblur rv32 rotate noise grain extract sharpen seamcarving croppadd
dynamicoverlay blendbench
])
VLC_ADD_PLUGINS([converter_fixed mono])
VLC_ADD_PLUGINS([trivial_resampler ugly_resampler])
VLC_ADD_PLUGINS([trivial_channel_mixer trivial_mixer])
...
...
@@ -6294,6 +6294,7 @@ AC_CONFIG_FILES([
modules/video_chroma/Makefile
modules/video_filter/Makefile
modules/video_filter/atmo/Makefile
modules/video_filter/dynamicoverlay/Makefile
modules/video_output/Makefile
modules/video_output/msw/Makefile
modules/video_output/qte/Makefile
...
...
include/vlc_vout.h
View file @
1ac8441a
...
...
@@ -211,10 +211,11 @@ struct subpicture_region_t
int
i_x
;
/**< position of region */
int
i_y
;
/**< position of region */
int
i_align
;
/**< alignment within a region */
int
i_alpha
;
/**< transparency */
char
*
psz_text
;
/**< text string comprising this region */
char
*
psz_html
;
/**< HTML version of subtitle (NULL = use psz_text) */
text_style_t
*
p_style
;
/*
a description of the text style formatting */
text_style_t
*
p_style
;
/**<
a description of the text style formatting */
subpicture_region_t
*
p_next
;
/**< next region in the list */
subpicture_region_t
*
p_cache
;
/**< modified version of this region */
...
...
modules/video_filter/Modules.am
View file @
1ac8441a
...
...
@@ -36,4 +36,5 @@ SOURCES_gaussianblur = gaussianblur.c
SOURCES_grain = grain.c
SOURCES_seamcarving = seamcarving.c
SOURCES_croppadd = croppadd.c
SOURCES_blendbench = blendbench.c
noinst_HEADERS = filter_common.h filter_picture.h
modules/video_filter/blendbench.c
0 → 100644
View file @
1ac8441a
/*****************************************************************************
* blendbench.c : blending benchmark plugin for vlc
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Author: Søren Bøg <avacore@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/vlc.h>
#include <vlc_sout.h>
#include <vlc_vout.h>
#include "vlc_filter.h"
#include "vlc_image.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
picture_t
*
Filter
(
filter_t
*
,
picture_t
*
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define LOOPS_TEXT N_("Number of time to blend")
#define LOOPS_LONGTEXT N_("The number of time the blend will be performed")
#define ALPHA_TEXT N_("Alpha of the blended image")
#define ALPHA_LONGTEXT N_("Alpha with which the blend image is blended")
#define BASE_IMAGE_TEXT N_("Image to be blended onto")
#define BASE_IMAGE_LONGTEXT N_("The image which will be used to blend onto")
#define BASE_CHROMA_TEXT N_("Chroma for the base image")
#define BASE_CHROMA_LONGTEXT N_("Chroma which the base image will be loaded in")
#define BLEND_IMAGE_TEXT N_("Image which will be blended.")
#define BLEND_IMAGE_LONGTEXT N_("The image blended onto the base image")
#define BLEND_CHROMA_TEXT N_("Chroma for the blend image")
#define BLEND_CHROMA_LONGTEXT N_("Chroma which the blend image will be loaded" \
"in")
#define CFG_PREFIX "blendbench-"
vlc_module_begin
();
set_description
(
_
(
"Blending benchmark filter"
)
);
set_shortname
(
_
(
"blendbench"
));
set_category
(
CAT_VIDEO
);
set_subcategory
(
SUBCAT_VIDEO_VFILTER
);
set_capability
(
"video filter2"
,
0
);
set_section
(
N_
(
"Benchmarking"
),
NULL
);
add_integer
(
CFG_PREFIX
"loops"
,
1000
,
NULL
,
LOOPS_TEXT
,
LOOPS_LONGTEXT
,
VLC_FALSE
);
add_integer_with_range
(
CFG_PREFIX
"alpha"
,
128
,
0
,
255
,
NULL
,
ALPHA_TEXT
,
ALPHA_LONGTEXT
,
VLC_FALSE
);
set_section
(
N_
(
"Base image"
),
NULL
);
add_file
(
CFG_PREFIX
"base-image"
,
NULL
,
NULL
,
BASE_IMAGE_TEXT
,
BASE_IMAGE_LONGTEXT
,
VLC_FALSE
);
add_string
(
CFG_PREFIX
"base-chroma"
,
"I420"
,
NULL
,
BASE_CHROMA_TEXT
,
BASE_CHROMA_LONGTEXT
,
VLC_FALSE
);
set_section
(
N_
(
"Blend image"
),
NULL
);
add_file
(
CFG_PREFIX
"blend-image"
,
NULL
,
NULL
,
BLEND_IMAGE_TEXT
,
BLEND_IMAGE_LONGTEXT
,
VLC_FALSE
);
add_string
(
CFG_PREFIX
"blend-chroma"
,
"YUVA"
,
NULL
,
BLEND_CHROMA_TEXT
,
BLEND_CHROMA_LONGTEXT
,
VLC_FALSE
);
set_callbacks
(
Create
,
Destroy
);
vlc_module_end
();
static
const
char
*
ppsz_filter_options
[]
=
{
"loops"
,
"alpha"
,
"base-image"
,
"base-chroma"
,
"blend-image"
,
"blend-chroma"
,
NULL
};
/*****************************************************************************
* filter_sys_t: filter method descriptor
*****************************************************************************/
struct
filter_sys_t
{
vlc_bool_t
b_done
;
int
i_loops
,
i_alpha
;
picture_t
*
p_base_image
;
picture_t
*
p_blend_image
;
vlc_fourcc_t
i_base_chroma
;
vlc_fourcc_t
i_blend_chroma
;
};
static
int
LoadImage
(
vlc_object_t
*
p_this
,
picture_t
**
pp_pic
,
vlc_fourcc_t
i_chroma
,
char
*
psz_file
,
const
char
*
psz_name
)
{
image_handler_t
*
p_image
;
video_format_t
fmt_in
,
fmt_out
;
memset
(
&
fmt_in
,
0
,
sizeof
(
video_format_t
)
);
memset
(
&
fmt_out
,
0
,
sizeof
(
video_format_t
)
);
fmt_out
.
i_chroma
=
i_chroma
;
p_image
=
image_HandlerCreate
(
p_this
);
*
pp_pic
=
image_ReadUrl
(
p_image
,
psz_file
,
&
fmt_in
,
&
fmt_out
);
image_HandlerDelete
(
p_image
);
if
(
*
pp_pic
==
NULL
)
{
msg_Err
(
p_this
,
"Unable to load %s image"
,
psz_name
);
return
VLC_EGENERIC
;
}
msg_Dbg
(
p_this
,
"%s image has dim %d x %d (Y plane)"
,
psz_name
,
(
*
pp_pic
)
->
p
[
Y_PLANE
].
i_visible_pitch
,
(
*
pp_pic
)
->
p
[
Y_PLANE
].
i_visible_lines
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Create: allocates video thread output method
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
;
char
*
psz_temp
;
/* Allocate structure */
p_filter
->
p_sys
=
malloc
(
sizeof
(
filter_sys_t
)
);
if
(
p_filter
->
p_sys
==
NULL
)
{
msg_Err
(
p_filter
,
"out of memory"
);
return
VLC_ENOMEM
;
}
p_sys
=
p_filter
->
p_sys
;
p_sys
->
b_done
=
VLC_FALSE
;
p_filter
->
pf_video_filter
=
Filter
;
/* needed to get options passed in transcode using the
* adjust{name=value} syntax */
config_ChainParse
(
p_filter
,
CFG_PREFIX
,
ppsz_filter_options
,
p_filter
->
p_cfg
);
p_sys
->
i_loops
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"loops"
);
p_sys
->
i_alpha
=
var_CreateGetIntegerCommand
(
p_filter
,
CFG_PREFIX
"alpha"
);
psz_temp
=
var_CreateGetStringCommand
(
p_filter
,
CFG_PREFIX
"base-chroma"
);
p_sys
->
i_base_chroma
=
VLC_FOURCC
(
psz_temp
[
0
],
psz_temp
[
1
],
psz_temp
[
2
],
psz_temp
[
3
]
);
LoadImage
(
p_this
,
&
p_sys
->
p_base_image
,
p_sys
->
i_base_chroma
,
var_CreateGetStringCommand
(
p_filter
,
CFG_PREFIX
"base-image"
),
"Base"
);
psz_temp
=
var_CreateGetStringCommand
(
p_filter
,
CFG_PREFIX
"blend-chroma"
);
p_sys
->
i_blend_chroma
=
VLC_FOURCC
(
psz_temp
[
0
],
psz_temp
[
1
],
psz_temp
[
2
],
psz_temp
[
3
]
);
LoadImage
(
p_this
,
&
p_sys
->
p_blend_image
,
p_sys
->
i_blend_chroma
,
var_CreateGetStringCommand
(
p_filter
,
CFG_PREFIX
"blend-image"
),
"Blend"
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Destroy: destroy video thread output method
*****************************************************************************/
static
void
Destroy
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
p_sys
->
p_base_image
->
pf_release
(
p_sys
->
p_base_image
);
p_sys
->
p_blend_image
->
pf_release
(
p_sys
->
p_blend_image
);
}
/*****************************************************************************
* Render: displays previously rendered output
*****************************************************************************/
static
picture_t
*
Filter
(
filter_t
*
p_filter
,
picture_t
*
p_pic
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
if
(
p_sys
->
b_done
)
{
return
p_pic
;
}
filter_t
*
p_blend
;
p_blend
=
vlc_object_create
(
p_filter
,
VLC_OBJECT_FILTER
);
vlc_object_attach
(
p_blend
,
p_filter
);
p_blend
->
fmt_out
.
video
=
p_sys
->
p_base_image
->
format
;
p_blend
->
fmt_in
.
video
=
p_sys
->
p_blend_image
->
format
;
p_blend
->
p_module
=
module_Need
(
p_blend
,
"video blending"
,
0
,
0
);
mtime_t
time
=
mdate
();
for
(
int
i_iter
=
0
;
i_iter
<
p_sys
->
i_loops
;
++
i_iter
)
{
p_blend
->
pf_video_blend
(
p_blend
,
p_sys
->
p_base_image
,
p_sys
->
p_base_image
,
p_sys
->
p_blend_image
,
0
,
0
,
p_sys
->
i_alpha
);
}
time
=
mdate
()
-
time
;
msg_Info
(
p_filter
,
"Blended %d images in %f sec."
,
p_sys
->
i_loops
,
time
/
1000000
.
0
f
);
msg_Info
(
p_filter
,
"Speed is: %f images/second, %f pixels/second"
,
(
float
)
p_sys
->
i_loops
/
time
*
1000000
,
(
float
)
p_sys
->
i_loops
/
time
*
1000000
*
p_sys
->
p_blend_image
->
p
[
Y_PLANE
].
i_visible_pitch
*
p_sys
->
p_blend_image
->
p
[
Y_PLANE
].
i_visible_lines
);
module_Unneed
(
p_blend
,
p_blend
->
p_module
);
vlc_object_detach
(
p_blend
);
vlc_object_release
(
p_blend
);
p_sys
->
b_done
=
VLC_TRUE
;
return
p_pic
;
}
modules/video_filter/dynamicoverlay/Modules.am
0 → 100644
View file @
1ac8441a
SOURCES_dynamicoverlay = dynamicoverlay_buffer.c dynamicoverlay_queue.c dynamicoverlay_list.c dynamicoverlay_commands.c dynamicoverlay.c
noinst_HEADERS = dynamicoverlay.h
modules/video_filter/dynamicoverlay/dynamicoverlay.c
0 → 100644
View file @
1ac8441a
/*****************************************************************************
* dynamicoverlay.c : dynamic overlay plugin for vlc
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Author: Søren Bøg <avacore@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/vlc.h>
#include <vlc_sout.h>
#include <vlc_vout.h>
#include <vlc_filter.h>
#include <vlc_osd.h>
#include <ctype.h>
#include <fcntl.h>
#include "dynamicoverlay.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
subpicture_t
*
Filter
(
filter_t
*
,
mtime_t
);
static
int
AdjustCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define INPUT_TEXT N_("Input FIFO")
#define INPUT_LONGTEXT N_("FIFO which will be read for commands")
#define OUTPUT_TEXT N_("Output FIFO")
#define OUTPUT_LONGTEXT N_("FIFO which will be written to for responses")
vlc_module_begin
();
set_description
(
_
(
"Dynamic video overlay"
)
);
set_shortname
(
_
(
"Overlay"
));
set_category
(
CAT_VIDEO
);
set_subcategory
(
SUBCAT_VIDEO_VFILTER
);
set_capability
(
"sub filter"
,
0
);
add_file
(
"overlay-input"
,
NULL
,
NULL
,
INPUT_TEXT
,
INPUT_LONGTEXT
,
VLC_FALSE
);
add_file
(
"overlay-output"
,
NULL
,
NULL
,
OUTPUT_TEXT
,
OUTPUT_LONGTEXT
,
VLC_FALSE
);
add_shortcut
(
"overlay"
);
set_callbacks
(
Create
,
Destroy
);
vlc_module_end
();
static
const
char
*
ppsz_filter_options
[]
=
{
"input"
,
"output"
,
NULL
};
/*****************************************************************************
* Create: allocates adjust video thread output method
*****************************************************************************
* This function allocates and initializes a adjust vout method.
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
filter_sys_t
*
p_sys
;
/* Allocate structure */
p_filter
->
p_sys
=
malloc
(
sizeof
(
filter_sys_t
)
);
if
(
p_filter
->
p_sys
==
NULL
)
{
msg_Err
(
p_filter
,
"out of memory"
);
return
VLC_ENOMEM
;
}
p_sys
=
p_filter
->
p_sys
;
BufferInit
(
&
p_sys
->
input
);
BufferInit
(
&
p_sys
->
output
);
QueueInit
(
&
p_sys
->
atomic
);
QueueInit
(
&
p_sys
->
pending
);
QueueInit
(
&
p_sys
->
processed
);
ListInit
(
&
p_sys
->
overlays
);
p_sys
->
i_inputfd
=
-
1
;
p_sys
->
i_outputfd
=
-
1
;
p_sys
->
b_updated
=
VLC_TRUE
;
p_sys
->
b_atomic
=
VLC_FALSE
;
p_filter
->
pf_sub_filter
=
Filter
;
config_ChainParse
(
p_filter
,
"overlay-"
,
ppsz_filter_options
,
p_filter
->
p_cfg
);
p_sys
->
psz_inputfile
=
var_CreateGetStringCommand
(
p_filter
,
"overlay-input"
);
p_sys
->
psz_outputfile
=
var_CreateGetStringCommand
(
p_filter
,
"overlay-output"
);
var_AddCallback
(
p_filter
,
"overlay-input"
,
AdjustCallback
,
p_sys
);
var_AddCallback
(
p_filter
,
"overlay-output"
,
AdjustCallback
,
p_sys
);
RegisterCommand
(
p_filter
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Destroy: destroy adjust video thread output method
*****************************************************************************
* Terminate an output method created by adjustCreateOutputMethod
*****************************************************************************/
static
void
Destroy
(
vlc_object_t
*
p_this
)
{
filter_t
*
p_filter
=
(
filter_t
*
)
p_this
;
BufferDestroy
(
&
p_filter
->
p_sys
->
input
);
BufferDestroy
(
&
p_filter
->
p_sys
->
output
);
QueueDestroy
(
&
p_filter
->
p_sys
->
atomic
);
QueueDestroy
(
&
p_filter
->
p_sys
->
pending
);
QueueDestroy
(
&
p_filter
->
p_sys
->
processed
);
ListDestroy
(
&
p_filter
->
p_sys
->
overlays
);
UnregisterCommand
(
p_filter
);
free
(
p_filter
->
p_sys
->
psz_inputfile
);
free
(
p_filter
->
p_sys
->
psz_outputfile
);
free
(
p_filter
->
p_sys
);
}
/*****************************************************************************
* Render: displays previously rendered output
*****************************************************************************
* This function send the currently rendered image to adjust modified image,
* waits until it is displayed and switch the two rendering buffers, preparing
* next frame.
*****************************************************************************/
static
subpicture_t
*
Filter
(
filter_t
*
p_filter
,
mtime_t
date
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
/* We might need to open these at any time. */
if
(
p_sys
->
i_inputfd
==
-
1
)
{
p_sys
->
i_inputfd
=
open
(
p_sys
->
psz_inputfile
,
O_RDONLY
|
O_NONBLOCK
);
if
(
p_sys
->
i_inputfd
==
-
1
)
{
msg_Warn
(
p_filter
,
"Failed to grab input file: %s (%s)"
,
p_sys
->
psz_inputfile
,
strerror
(
errno
)
);
}
else
{
msg_Info
(
p_filter
,
"Grabbed input file: %s"
,
p_sys
->
psz_inputfile
);
}
}
if
(
p_sys
->
i_outputfd
==
-
1
)
{
p_sys
->
i_outputfd
=
open
(
p_sys
->
psz_outputfile
,
O_WRONLY
|
O_NONBLOCK
);
if
(
p_sys
->
i_outputfd
==
-
1
)
{
if
(
errno
!=
ENXIO
)
{
msg_Warn
(
p_filter
,
"Failed to grab output file: %s (%s)"
,
p_sys
->
psz_outputfile
,
strerror
(
errno
)
);
}
}
else
{
msg_Info
(
p_filter
,
"Grabbed output file: %s"
,
p_sys
->
psz_outputfile
);
}
}
/* Read any waiting commands */
if
(
p_sys
->
i_inputfd
!=
-
1
)
{
char
p_buffer
[
1024
];
ssize_t
i_len
=
read
(
p_sys
->
i_inputfd
,
p_buffer
,
1024
);
if
(
i_len
==
-
1
)
{
/* We hit an error */
if
(
errno
!=
EAGAIN
)
{
msg_Warn
(
p_filter
,
"Error on input file: %s"
,
strerror
(
errno
)
);
close
(
p_sys
->
i_inputfd
);
p_sys
->
i_inputfd
=
-
1
;
}
}
else
if
(
i_len
==
0
)
{
/* We hit the end-of-file */
}
else
{
BufferAdd
(
&
p_sys
->
input
,
p_buffer
,
i_len
);
}
}
/* Parse any complete commands */
char
*
p_end
,
*
p_cmd
;
while
(
(
p_end
=
memchr
(
p_sys
->
input
.
p_begin
,
'\n'
,
p_sys
->
input
.
i_length
)
)
)
{
commanddesc_t
*
p_cur
=
NULL
;
vlc_bool_t
b_found
=
VLC_FALSE
;
size_t
i_index
=
0
;
*
p_end
=
'\0'
;
p_cmd
=
BufferGetToken
(
&
p_sys
->
input
);
msg_Info
(
p_filter
,
"Search command: %s"
,
p_cmd
);
for
(
i_index
=
0
;
i_index
<
p_sys
->
i_commands
;
i_index
++
)
{
p_cur
=
p_sys
->
pp_commands
[
i_index
];
if
(
!
strncmp
(
p_cur
->
psz_command
,
p_cmd
,
strlen
(
p_cur
->
psz_command
)
)
)
{
p_cmd
[
strlen
(
p_cur
->
psz_command
)]
=
'\0'
;
b_found
=
VLC_TRUE
;
break
;
}
}
if
(
!
b_found
)
{
/* No matching command */
msg_Err
(
p_filter
,
"Got invalid command: %s"
,
p_cmd
);
BufferPrintf
(
&
p_sys
->
output
,
"FAILURE: %d Invalid Command
\n
"
,
VLC_EGENERIC
);
}
else
{
msg_Info
(
p_filter
,
"Got valid command: %s"
,
p_cmd
);
command_t
*
p_cmddesc
=
malloc
(
sizeof
(
command_t
)
);
if
(
!
p_cmddesc
)
return
NULL
;
p_cmd
=
p_cmd
+
strlen
(
p_cur
->
psz_command
)
+
1
;
p_cmddesc
->
p_command
=
p_cur
;
p_cmddesc
->
p_command
->
pf_parser
(
p_cmd
,
p_end
,
&
p_cmddesc
->
params
);
if
(
(
p_cmddesc
->
p_command
->
b_atomic
==
VLC_TRUE
)
&&
(
p_sys
->
b_atomic
==
VLC_TRUE
)
)
QueueEnqueue
(
&
p_sys
->
atomic
,
p_cmddesc
);
else
QueueEnqueue
(
&
p_sys
->
pending
,
p_cmddesc
);
}
BufferDel
(
&
p_sys
->
input
,
p_end
-
p_sys
->
input
.
p_begin
+
1
);
}
/* Process any pending commands */
command_t
*
p_command
=
NULL
;
while
(
(
p_command
=
QueueDequeue
(
&
p_sys
->
pending
))
)
{
p_command
->
i_status
=
p_command
->
p_command
->
pf_execute
(
p_filter
,
&
p_command
->
params
,
&
p_command
->
results
);
QueueEnqueue
(
&
p_sys
->
processed
,
p_command
);
}
/* Output any processed commands */
while
(
(
p_command
=
QueueDequeue
(
&
p_sys
->
processed
))
)
{
if
(
p_command
->
i_status
==
VLC_SUCCESS
)
{
const
char
*
psz_success
=
"SUCCESS:"
;
const
char
*
psz_nl
=
"
\n
"
;
BufferAdd
(
&
p_sys
->
output
,
psz_success
,
8
);
p_command
->
p_command
->
pf_unparse
(
&
p_command
->
results
,
&
p_sys
->
output
);
BufferAdd
(
&
p_sys
->
output
,
psz_nl
,
1
);
}
else
{
BufferPrintf
(
&
p_sys
->
output
,
"FAILURE: %d
\n
"
,
p_command
->
i_status
);
}
}
/* Try emptying the output buffer */
if
(
p_sys
->
i_outputfd
!=
-
1
)
{
ssize_t
i_len
=
write
(
p_sys
->
i_outputfd
,
p_sys
->
output
.
p_begin
,
p_sys
->
output
.
i_length
);
if
(
i_len
==
-
1
)
{
/* We hit an error */
if
(
errno
!=
EAGAIN
)
{
msg_Warn
(
p_filter
,
"Error on output file: %s"
,
strerror
(
errno
)
);
close
(
p_sys
->
i_outputfd
);
p_sys
->
i_outputfd
=
-
1
;
}
}
else
{
BufferDel
(
&
p_sys
->
output
,
i_len
);
}
}
if
(
p_sys
->
b_updated
==
VLC_FALSE
)
return
NULL
;
subpicture_t
*
p_spu
=
NULL
;
overlay_t
*
p_overlay
=
NULL
;
p_spu
=
p_filter
->
pf_sub_buffer_new
(
p_filter
);
if
(
!
p_spu
)
{
msg_Err
(
p_filter
,
"cannot allocate subpicture"
);
return
NULL
;
}
p_spu
->
i_flags
=
OSD_ALIGN_LEFT
|
OSD_ALIGN_TOP
;
p_spu
->
i_x
=
0
;
p_spu
->
i_y
=
0
;
p_spu
->
b_absolute
=
VLC_TRUE
;
p_spu
->
i_start
=
date
;
p_spu
->
i_stop
=
0
;
p_spu
->
b_ephemer
=
VLC_TRUE
;
subpicture_region_t
**
pp_region
=
&
p_spu
->
p_region
;
while
(
(
p_overlay
=
ListWalk
(
&
p_sys
->
overlays
))
)
{
msg_Dbg
(
p_filter
,
"Displaying overlay: %4.4s, %d, %d, %d"
,
(
char
*
)
&
p_overlay
->
format
.
i_chroma
,
p_overlay
->
i_x
,
p_overlay
->
i_y
,
p_overlay
->
i_alpha
);
if
(
p_overlay
->
format
.
i_chroma
==
VLC_FOURCC
(
'T'
,
'E'
,
'X'
,
'T'
)
)
{
*
pp_region
=
p_spu
->
pf_create_region
(
VLC_OBJECT
(
p_filter
),
&
p_overlay
->
format
);
if
(
!*
pp_region
)
break
;
(
*
pp_region
)
->
psz_text
=
strdup
(
p_overlay
->
data
.
p_text
);
(
*
pp_region
)
->
p_style
=
malloc
(
sizeof
(
struct
text_style_t
)
);
if
(
!
(
*
pp_region
)
->
p_style
)
{
p_spu
->
pf_destroy_region
(
VLC_OBJECT
(
p_filter
),
(
*
pp_region
)
);
*
pp_region
=
NULL
;
break
;
}
p_filter
->
p_libvlc
->
pf_memcpy
(
(
*
pp_region
)
->
p_style
,
&
p_overlay
->
fontstyle
,
sizeof
(
struct
text_style_t
)
);
}
else
{
picture_t
clone
;
if
(
vout_AllocatePicture
(
p_filter
,
&
clone
,
p_overlay
->
format
.
i_chroma
,
p_overlay
->
format
.
i_width
,
p_overlay
->
format
.
i_height
,
p_overlay
->
format
.
i_aspect
)
)
{
msg_Err
(
p_filter
,
"cannot allocate picture"
);
continue
;
}
vout_CopyPicture
(
p_filter
,
&
clone
,
p_overlay
->
data
.
p_pic
);
*
pp_region
=
p_spu
->
pf_make_region
(
VLC_OBJECT
(
p_filter
),
&
p_overlay
->
format
,
&
clone
);
if
(
!*
pp_region
)
{
msg_Err
(
p_filter
,
"cannot allocate subpicture region"
);
continue
;
}
}
(
*
pp_region
)
->
i_x
=
p_overlay
->
i_x
;
(
*
pp_region
)
->
i_y
=
p_overlay
->
i_y
;
(
*
pp_region
)
->
i_align
=
OSD_ALIGN_LEFT
|
OSD_ALIGN_TOP
;
(
*
pp_region
)
->
i_alpha
=
p_overlay
->
i_alpha
;
pp_region
=
&
(
*
pp_region
)
->
p_next
;
}
p_sys
->
b_updated
=
VLC_FALSE
;
return
p_spu
;
}
static
int
AdjustCallback
(
vlc_object_t
*
p_this
,
char
const
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_data
;
VLC_UNUSED
(
p_this
);
VLC_UNUSED
(
oldval
);
if
(
!
strncmp
(
psz_var
,
"overlay-input"
,
13
)
)
p_sys
->
psz_inputfile
=
newval
.
psz_string
;
else
if
(
!
strncmp
(
psz_var
,
"overlay-output"
,
14
)
)
p_sys
->
psz_outputfile
=
newval
.
psz_string
;
return
VLC_EGENERIC
;
}
modules/video_filter/dynamicoverlay/dynamicoverlay.h
0 → 100644
View file @
1ac8441a
/*****************************************************************************
* dynamicoverlay.h : dynamic overlay plugin for vlc
*****************************************************************************
* Copyright (C) 2008 the VideoLAN team
* $Id$
*
* Author: Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef DYNAMIC_OVERLAY_H
#define DYNAMIC_OVERLAY_H 1
#include <vlc/vlc.h>
#include <vlc_filter.h>
/*****************************************************************************
* buffer_t: Command and response buffer
*****************************************************************************/
typedef
struct
buffer_t
{
size_t
i_size
;
/**< Size of the allocated memory */
size_t
i_length
;
/**< Length of the stored data */
char
*
p_memory
;
/**< Start of the allocated memory */
char
*
p_begin
;
/**< Start of the stored data */
}
buffer_t
;
int
BufferInit
(
buffer_t
*
p_buffer
);
int
BufferDestroy
(
buffer_t
*
p_buffer
);
int
BufferAdd
(
buffer_t
*
p_buffer
,
const
char
*
p_data
,
size_t
i_len
);
int
BufferPrintf
(
buffer_t
*
p_buffer
,
const
char
*
p_fmt
,
...
);
int
BufferDel
(
buffer_t
*
p_buffer
,
int
i_len
);
char
*
BufferGetToken
(
buffer_t
*
p_buffer
);
/*****************************************************************************
* Command structures
*****************************************************************************/
/** struct commandparams_t - command params structure */
typedef
struct
commandparams_t
{
int32_t
i_id
;
/*< overlay id */
int32_t
i_shmid
;
/*< shared memory identifier */
vlc_fourcc_t
fourcc
;
/*< chroma */
int32_t
i_x
;
/*< x position of overlay */
int32_t
i_y
;
/*< y position of overlay */
int32_t
i_width
;
/*< width of overlay */
int32_t
i_height
;
/*< height of overlay */
int32_t
i_alpha
;
/*< alpha value of overlay */
struct
text_style_t
fontstyle
;
/*< text style */
vlc_bool_t
b_visible
;
/*< visibility flag of overlay */
}
commandparams_t
;
typedef
struct
commanddesc_t
{
const
char
*
psz_command
;
vlc_bool_t
b_atomic
;
int
(
*
pf_parser
)
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
);
int
(
*
pf_execute
)
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
);
int
(
*
pf_unparse
)
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
);
}
commanddesc_t
;
typedef
struct
command_t
{
struct
commanddesc_t
*
p_command
;
int
i_status
;
commandparams_t
params
;
commandparams_t
results
;
struct
command_t
*
p_next
;
}
command_t
;
void
RegisterCommand
(
filter_t
*
p_filter
);
void
UnregisterCommand
(
filter_t
*
p_filter
);
/*****************************************************************************
* queue_t: Command queue
*****************************************************************************/
typedef
struct
queue_t
{
command_t
*
p_head
;
/**< Head (first entry) of the queue */
command_t
*
p_tail
;
/**< Tail (last entry) of the queue */
}
queue_t
;
int
QueueInit
(
queue_t
*
p_queue
);
int
QueueDestroy
(
queue_t
*
p_queue
);
int
QueueEnqueue
(
queue_t
*
p_queue
,
command_t
*
p_cmd
);
command_t
*
QueueDequeue
(
queue_t
*
p_queue
);
int
QueueTransfer
(
queue_t
*
p_sink
,
queue_t
*
p_source
);
/*****************************************************************************
* overlay_t: Overlay descriptor
*****************************************************************************/
typedef
struct
overlay_t
{
int
i_x
,
i_y
;
int
i_alpha
;
vlc_bool_t
b_active
;
video_format_t
format
;
struct
text_style_t
fontstyle
;
union
{
picture_t
*
p_pic
;
char
*
p_text
;
}
data
;
}
overlay_t
;
overlay_t
*
OverlayCreate
(
void
);
int
OverlayDestroy
(
overlay_t
*
p_ovl
);
/*****************************************************************************
* list_t: Command queue
*****************************************************************************/
typedef
struct
list_t
{
overlay_t
**
pp_head
,
**
pp_tail
;
}
list_t
;
int
ListInit
(
list_t
*
p_list
);
int
ListDestroy
(
list_t
*
p_list
);
ssize_t
ListAdd
(
list_t
*
p_list
,
overlay_t
*
p_new
);
int
ListRemove
(
list_t
*
p_list
,
size_t
i_idx
);
overlay_t
*
ListGet
(
list_t
*
p_list
,
size_t
i_idx
);
overlay_t
*
ListWalk
(
list_t
*
p_list
);
/*****************************************************************************
* filter_sys_t: adjust filter method descriptor
*****************************************************************************/
struct
filter_sys_t
{
buffer_t
input
,
output
;
int
i_inputfd
,
i_outputfd
;
char
*
psz_inputfile
,
*
psz_outputfile
;
commanddesc_t
**
pp_commands
;
/* array of commands */
size_t
i_commands
;
vlc_bool_t
b_updated
,
b_atomic
;
queue_t
atomic
,
pending
,
processed
;
list_t
overlays
;
};
#endif
modules/video_filter/dynamicoverlay/dynamicoverlay_buffer.c
0 → 100644
View file @
1ac8441a
/*****************************************************************************
* dynamicoverlay_buffer.h : dynamic overlay buffer
*****************************************************************************
* Copyright (C) 2008 the VideoLAN team
* $Id$
*
* Author: Søren Bøg <avacore@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/vlc.h>
#include <vlc_osd.h>
#include <vlc_filter.h>
#include <ctype.h>
#include "dynamicoverlay.h"
/*****************************************************************************
* buffer_t: Command and response buffer
*****************************************************************************/
int
BufferInit
(
buffer_t
*
p_buffer
)
{
memset
(
p_buffer
,
0
,
sizeof
(
buffer_t
)
);
p_buffer
->
p_memory
=
NULL
;
p_buffer
->
p_begin
=
NULL
;
return
VLC_SUCCESS
;
}
int
BufferDestroy
(
buffer_t
*
p_buffer
)
{
if
(
p_buffer
->
p_memory
!=
NULL
)
{
free
(
p_buffer
->
p_memory
);
}
p_buffer
->
p_memory
=
NULL
;
p_buffer
->
p_begin
=
NULL
;
return
VLC_SUCCESS
;
}
char
*
BufferGetToken
(
buffer_t
*
p_buffer
)
{
char
*
p_char
=
p_buffer
->
p_begin
;
while
(
isspace
(
p_char
[
0
]
)
||
p_char
[
0
]
==
'\0'
)
{
if
(
p_char
<=
(
p_buffer
->
p_begin
+
p_buffer
->
i_length
)
)
p_char
++
;
else
return
NULL
;
}
return
p_char
;
}
int
BufferAdd
(
buffer_t
*
p_buffer
,
const
char
*
p_data
,
size_t
i_len
)
{
if
(
(
p_buffer
->
i_size
-
p_buffer
->
i_length
-
(
p_buffer
->
p_begin
-
p_buffer
->
p_memory
)
)
<
i_len
)
{
/* We'll have to do some rearranging to fit the new data. */
if
(
(
p_buffer
->
i_size
-
p_buffer
->
i_length
)
>=
i_len
)
{
/* We have room in the current buffer, just need to move it */
memmove
(
p_buffer
->
p_memory
,
p_buffer
->
p_begin
,
p_buffer
->
i_length
);
p_buffer
->
p_begin
=
p_buffer
->
p_memory
;
}
else
{
// We need a bigger buffer
size_t
i_newsize
=
1024
;
while
(
i_newsize
<
p_buffer
->
i_length
+
i_len
)
i_newsize
*=
2
;
/* TODO: Should I handle wrapping here? */
/* I'm not using realloc here, as I can avoid a memcpy/memmove in
some (most?) cases, and reset the start of the buffer. */
char
*
p_newdata
=
malloc
(
i_newsize
);
if
(
p_newdata
==
NULL
)
return
VLC_ENOMEM
;
if
(
p_buffer
->
p_begin
!=
NULL
)
{
memcpy
(
p_newdata
,
p_buffer
->
p_begin
,
p_buffer
->
i_length
);
free
(
p_buffer
->
p_memory
);
}
p_buffer
->
p_memory
=
p_buffer
->
p_begin
=
p_newdata
;
p_buffer
->
i_size
=
i_newsize
;
}
}
/* Add the new data to the end of the current */
memcpy
(
p_buffer
->
p_begin
+
p_buffer
->
i_length
,
p_data
,
i_len
);
p_buffer
->
i_length
+=
i_len
;
return
VLC_SUCCESS
;
}
int
BufferPrintf
(
buffer_t
*
p_buffer
,
const
char
*
p_fmt
,
...
)
{
int
i_len
;
int
status
;
char
*
psz_data
;
va_list
va_list1
,
va_list2
;
va_start
(
va_list1
,
p_fmt
);
va_copy
(
va_list2
,
va_list1
);
i_len
=
vsnprintf
(
NULL
,
0
,
p_fmt
,
va_list1
);
if
(
i_len
<
0
)
return
VLC_EGENERIC
;
va_end
(
va_list1
);
psz_data
=
malloc
(
i_len
+
1
);
if
(
psz_data
==
NULL
)
{
return
VLC_ENOMEM
;
}
if
(
vsnprintf
(
psz_data
,
i_len
+
1
,
p_fmt
,
va_list2
)
!=
i_len
)
{
return
VLC_EGENERIC
;
}
va_end
(
va_list2
);
status
=
BufferAdd
(
p_buffer
,
psz_data
,
i_len
);
free
(
psz_data
);
return
status
;
}
int
BufferDel
(
buffer_t
*
p_buffer
,
int
i_len
)
{
p_buffer
->
i_length
-=
i_len
;
if
(
p_buffer
->
i_length
==
0
)
{
/* No data, we can reset the buffer now. */
p_buffer
->
p_begin
=
p_buffer
->
p_memory
;
}
else
{
p_buffer
->
p_begin
+=
i_len
;
}
return
VLC_SUCCESS
;
}
modules/video_filter/dynamicoverlay/dynamicoverlay_commands.c
0 → 100644
View file @
1ac8441a
/*****************************************************************************
* dynamicoverlay_commands.c : dynamic overlay plugin commands
*****************************************************************************
* Copyright (C) 2008 the VideoLAN team
* $Id$
*
* Author: Søren Bøg <avacore@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/vlc.h>
#include <vlc_arrays.h>
#include <vlc_vout.h>
#include <vlc_filter.h>
#include <vlc_osd.h>
#include <string.h>
#include <ctype.h>
#include <sys/shm.h>
#include "dynamicoverlay.h"
/*****************************************************************************
* overlay_t: Overlay descriptor
*****************************************************************************/
overlay_t
*
OverlayCreate
(
void
)
{
overlay_t
*
p_ovl
=
malloc
(
sizeof
(
overlay_t
)
);
if
(
p_ovl
==
NULL
)
return
NULL
;
memset
(
p_ovl
,
0
,
sizeof
(
overlay_t
)
);
p_ovl
->
i_x
=
p_ovl
->
i_y
=
0
;
p_ovl
->
i_alpha
=
0xFF
;
p_ovl
->
b_active
=
VLC_FALSE
;
vout_InitFormat
(
&
p_ovl
->
format
,
VLC_FOURCC
(
'\0'
,
'\0'
,
'\0'
,
'\0'
)
,
0
,
0
,
VOUT_ASPECT_FACTOR
);
memcpy
(
&
p_ovl
->
fontstyle
,
&
default_text_style
,
sizeof
(
struct
text_style_t
)
);
p_ovl
->
data
.
p_text
=
NULL
;
return
p_ovl
;
}
int
OverlayDestroy
(
overlay_t
*
p_ovl
)
{
if
(
p_ovl
->
data
.
p_text
!=
NULL
)
free
(
p_ovl
->
data
.
p_text
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Command parsers
*****************************************************************************/
static
int
skip_space
(
char
**
psz_command
)
{
char
*
psz_temp
=
*
psz_command
;
while
(
isspace
(
*
psz_temp
)
)
{
++
psz_temp
;
}
if
(
psz_temp
==
*
psz_command
)
{
return
VLC_EGENERIC
;
}
*
psz_command
=
psz_temp
;
return
VLC_SUCCESS
;
}
static
int
parse_digit
(
char
**
psz_command
,
int32_t
*
value
)
{
char
*
psz_temp
;
*
value
=
strtol
(
*
psz_command
,
&
psz_temp
,
10
);
if
(
psz_temp
==
*
psz_command
)
{
return
VLC_EGENERIC
;
}
*
psz_command
=
psz_temp
;
return
VLC_SUCCESS
;
}
static
int
parse_char
(
char
**
psz_command
,
char
**
psz_end
,
int
count
,
char
*
psz_value
)
{
if
(
*
psz_end
-
*
psz_command
<
count
)
{
return
VLC_EGENERIC
;
}
memcpy
(
psz_value
,
*
psz_command
,
count
);
*
psz_command
+=
count
;
return
VLC_SUCCESS
;
}
static
int
parser_DataSharedMem
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
/* Parse: 0 128 128 RGBA 9404459 */
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_id
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_width
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_height
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isascii
(
*
psz_command
)
)
{
if
(
parse_char
(
&
psz_command
,
&
psz_end
,
4
,
(
char
*
)
&
p_params
->
fourcc
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_shmid
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
static
int
parser_Id
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
(
void
)(
psz_end
);
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_id
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
static
int
parser_None
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
(
void
)(
psz_command
);
(
void
)(
psz_end
);
(
void
)(
p_params
);
return
VLC_SUCCESS
;
}
static
int
parser_SetAlpha
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
(
void
)(
psz_end
);
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_id
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_alpha
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
static
int
parser_SetPosition
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
(
void
)(
psz_end
);
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_id
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_x
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_y
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
static
int
parser_SetTextAlpha
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
(
void
)(
psz_end
);
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_id
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
fontstyle
.
i_font_alpha
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
static
int
parser_SetTextColor
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
int
r
,
g
,
b
;
(
void
)(
psz_end
);
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_id
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
r
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
g
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
b
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
p_params
->
fontstyle
.
i_font_color
=
(
r
<<
24
)
|
(
g
<<
16
)
|
(
b
<<
8
);
return
VLC_SUCCESS
;
}
static
int
parser_SetTextSize
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
(
void
)(
psz_end
);
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_id
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
fontstyle
.
i_font_size
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
}
static
int
parser_SetVisibility
(
char
*
psz_command
,
char
*
psz_end
,
commandparams_t
*
p_params
)
{
(
void
)(
psz_end
);
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
if
(
parse_digit
(
&
psz_command
,
&
p_params
->
i_id
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
}
skip_space
(
&
psz_command
);
if
(
isdigit
(
*
psz_command
)
)
{
int32_t
i_vis
=
0
;
if
(
parse_digit
(
&
psz_command
,
&
i_vis
)
==
VLC_EGENERIC
)
return
VLC_EGENERIC
;
p_params
->
b_visible
=
(
i_vis
==
1
)
?
VLC_TRUE
:
VLC_FALSE
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Command unparser functions
*****************************************************************************/
static
int
unparse_default
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
)
{
(
void
)(
p_results
);
VLC_UNUSED
(
p_output
);
return
VLC_SUCCESS
;
}
static
int
unparse_GenImage
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
)
{
int
ret
=
BufferPrintf
(
p_output
,
" %d"
,
p_results
->
i_id
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
return
VLC_SUCCESS
;
}
static
int
unparse_GetAlpha
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
)
{
int
ret
=
BufferPrintf
(
p_output
,
" %d"
,
p_results
->
i_alpha
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
return
VLC_SUCCESS
;
}
static
int
unparse_GetPosition
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
)
{
int
ret
=
BufferPrintf
(
p_output
,
" %d"
,
p_results
->
i_x
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
ret
=
BufferPrintf
(
p_output
,
" %d"
,
p_results
->
i_y
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
return
VLC_SUCCESS
;
}
static
int
unparse_GetTextAlpha
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
)
{
int
ret
=
BufferPrintf
(
p_output
,
" %d"
,
p_results
->
fontstyle
.
i_font_alpha
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
return
VLC_SUCCESS
;
}
static
int
unparse_GetTextColor
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
)
{
int
ret
=
BufferPrintf
(
p_output
,
" %d"
,
(
p_results
->
fontstyle
.
i_font_color
&
0xff0000
)
>>
24
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
ret
=
BufferPrintf
(
p_output
,
" %d"
,
(
p_results
->
fontstyle
.
i_font_color
&
0x00ff00
)
>>
16
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
ret
=
BufferPrintf
(
p_output
,
" %d"
,
(
p_results
->
fontstyle
.
i_font_color
&
0x0000ff
)
>>
8
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
return
VLC_SUCCESS
;
}
static
int
unparse_GetTextSize
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
)
{
int
ret
=
BufferPrintf
(
p_output
,
" %d"
,
p_results
->
fontstyle
.
i_font_size
);
if
(
ret
!=
VLC_SUCCESS
)
return
ret
;
return
VLC_SUCCESS
;
}
static
int
unparse_GetVisibility
(
const
commandparams_t
*
p_results
,
buffer_t
*
p_output
)
{
int
ret
=
BufferPrintf
(
p_output
,
" %d"
,
(
p_results
->
b_visible
?
1
:
0
)
);
if
(
ret
!=
VLC_SUCCESS
)
{
return
ret
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Command functions
*****************************************************************************/
static
int
exec_DataSharedMem
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
struct
shmid_ds
shminfo
;
overlay_t
*
p_ovl
;
size_t
i_size
;
(
void
)(
p_results
);
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
{
msg_Err
(
p_filter
,
"Invalid overlay: %d"
,
p_params
->
i_id
);
return
VLC_EGENERIC
;
}
if
(
shmctl
(
p_params
->
i_shmid
,
IPC_STAT
,
&
shminfo
)
==
-
1
)
{
msg_Err
(
p_filter
,
"Unable to access shared memory"
);
return
VLC_EGENERIC
;
}
i_size
=
shminfo
.
shm_segsz
;
if
(
p_params
->
fourcc
==
VLC_FOURCC
(
'T'
,
'E'
,
'X'
,
'T'
)
)
{
char
*
p_data
;
if
(
(
p_params
->
i_height
!=
1
)
||
(
p_params
->
i_width
<
1
)
)
{
msg_Err
(
p_filter
,
"Invalid width and/or height. when specifing text height "
"must be 1 and width the number of bytes in the string, "
"including the null terminator"
);
return
VLC_EGENERIC
;
}
if
(
(
size_t
)
p_params
->
i_width
>
i_size
)
{
msg_Err
(
p_filter
,
"Insufficient data in shared memory. need %d, got %d"
,
p_params
->
i_width
,
i_size
);
return
VLC_EGENERIC
;
}
p_ovl
->
data
.
p_text
=
malloc
(
p_params
->
i_width
);
if
(
p_ovl
->
data
.
p_text
==
NULL
)
{
msg_Err
(
p_filter
,
"Unable to allocate string storage"
);
return
VLC_ENOMEM
;
}
vout_InitFormat
(
&
p_ovl
->
format
,
VLC_FOURCC
(
'T'
,
'E'
,
'X'
,
'T'
),
0
,
0
,
0
);
p_data
=
shmat
(
p_params
->
i_shmid
,
NULL
,
SHM_RDONLY
);
if
(
p_data
==
NULL
)
{
msg_Err
(
p_filter
,
"Unable to attach to shared memory"
);
free
(
p_ovl
->
data
.
p_text
);
p_ovl
->
data
.
p_text
=
NULL
;
return
VLC_ENOMEM
;
}
memcpy
(
p_ovl
->
data
.
p_text
,
p_data
,
p_params
->
i_width
);
shmdt
(
p_data
);
}
else
{
uint8_t
*
p_data
,
*
p_in
;
size_t
i_neededsize
=
0
;
p_ovl
->
data
.
p_pic
=
malloc
(
sizeof
(
picture_t
)
);
if
(
p_ovl
->
data
.
p_pic
==
NULL
)
{
msg_Err
(
p_filter
,
"Unable to allocate picture structure"
);
return
VLC_ENOMEM
;
}
vout_InitFormat
(
&
p_ovl
->
format
,
p_params
->
fourcc
,
p_params
->
i_width
,
p_params
->
i_height
,
VOUT_ASPECT_FACTOR
);
if
(
vout_AllocatePicture
(
p_filter
,
p_ovl
->
data
.
p_pic
,
p_ovl
->
format
.
i_chroma
,
p_params
->
i_width
,
p_params
->
i_height
,
p_ovl
->
format
.
i_aspect
)
)
{
msg_Err
(
p_filter
,
"Unable to allocate picture"
);
free
(
p_ovl
->
data
.
p_pic
);
p_ovl
->
data
.
p_pic
=
NULL
;
return
VLC_ENOMEM
;
}
for
(
size_t
i_plane
=
0
;
i_plane
<
(
size_t
)
p_ovl
->
data
.
p_pic
->
i_planes
;
++
i_plane
)
{
i_neededsize
+=
p_ovl
->
data
.
p_pic
->
p
[
i_plane
].
i_visible_lines
*
p_ovl
->
data
.
p_pic
->
p
[
i_plane
].
i_visible_pitch
;
}
if
(
i_neededsize
>
i_size
)
{
msg_Err
(
p_filter
,
"Insufficient data in shared memory. need %d, got %d"
,
i_neededsize
,
i_size
);
p_ovl
->
data
.
p_pic
->
pf_release
(
p_ovl
->
data
.
p_pic
);
free
(
p_ovl
->
data
.
p_pic
);
p_ovl
->
data
.
p_pic
=
NULL
;
return
VLC_EGENERIC
;
}
p_data
=
shmat
(
p_params
->
i_shmid
,
NULL
,
SHM_RDONLY
);
if
(
p_data
==
NULL
)
{
msg_Err
(
p_filter
,
"Unable to attach to shared memory"
);
p_ovl
->
data
.
p_pic
->
pf_release
(
p_ovl
->
data
.
p_pic
);
free
(
p_ovl
->
data
.
p_pic
);
p_ovl
->
data
.
p_pic
=
NULL
;
return
VLC_ENOMEM
;
}
p_in
=
p_data
;
for
(
size_t
i_plane
=
0
;
i_plane
<
(
size_t
)
p_ovl
->
data
.
p_pic
->
i_planes
;
++
i_plane
)
{
uint8_t
*
p_out
=
p_ovl
->
data
.
p_pic
->
p
[
i_plane
].
p_pixels
;
for
(
size_t
i_line
=
0
;
i_line
<
(
size_t
)
p_ovl
->
data
.
p_pic
->
p
[
i_plane
].
i_visible_lines
;
++
i_line
)
{
p_filter
->
p_libvlc
->
pf_memcpy
(
p_out
,
p_in
,
p_ovl
->
data
.
p_pic
->
p
[
i_plane
].
i_visible_pitch
);
p_out
+=
p_ovl
->
data
.
p_pic
->
p
[
i_plane
].
i_pitch
;
p_in
+=
p_ovl
->
data
.
p_pic
->
p
[
i_plane
].
i_visible_pitch
;
}
}
shmdt
(
p_data
);
}
p_sys
->
b_updated
=
p_ovl
->
b_active
;
return
VLC_SUCCESS
;
}
static
int
exec_DeleteImage
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_results
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
p_sys
->
b_updated
=
VLC_TRUE
;
return
ListRemove
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
}
static
int
exec_EndAtomic
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_params
);
(
void
)(
p_results
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
QueueTransfer
(
&
p_sys
->
pending
,
&
p_sys
->
atomic
);
p_sys
->
b_atomic
=
VLC_FALSE
;
return
VLC_SUCCESS
;
}
static
int
exec_GenImage
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_params
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
OverlayCreate
();
if
(
p_ovl
==
NULL
)
return
VLC_ENOMEM
;
ssize_t
i_idx
=
ListAdd
(
&
p_sys
->
overlays
,
p_ovl
);
if
(
i_idx
<
0
)
return
i_idx
;
p_results
->
i_id
=
i_idx
;
return
VLC_SUCCESS
;
}
static
int
exec_GetAlpha
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_results
->
i_alpha
=
p_ovl
->
i_alpha
;
return
VLC_SUCCESS
;
}
static
int
exec_GetPosition
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_results
->
i_x
=
p_ovl
->
i_x
;
p_results
->
i_y
=
p_ovl
->
i_y
;
return
VLC_SUCCESS
;
}
static
int
exec_GetTextAlpha
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_results
->
fontstyle
.
i_font_alpha
=
p_ovl
->
fontstyle
.
i_font_alpha
;
return
VLC_SUCCESS
;
}
static
int
exec_GetTextColor
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_results
->
fontstyle
.
i_font_color
=
p_ovl
->
fontstyle
.
i_font_color
;
return
VLC_SUCCESS
;
}
static
int
exec_GetTextSize
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_results
->
fontstyle
.
i_font_size
=
p_ovl
->
fontstyle
.
i_font_size
;
return
VLC_SUCCESS
;
}
static
int
exec_GetVisibility
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_results
->
b_visible
=
(
p_ovl
->
b_active
==
VLC_TRUE
)
?
1
:
0
;
return
VLC_SUCCESS
;
}
static
int
exec_SetAlpha
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_results
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_ovl
->
i_alpha
=
p_params
->
i_alpha
;
p_sys
->
b_updated
=
p_ovl
->
b_active
;
return
VLC_SUCCESS
;
}
static
int
exec_SetPosition
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_results
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_ovl
->
i_x
=
p_params
->
i_x
;
p_ovl
->
i_y
=
p_params
->
i_y
;
p_sys
->
b_updated
=
p_ovl
->
b_active
;
return
VLC_SUCCESS
;
}
static
int
exec_SetTextAlpha
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_results
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_ovl
->
fontstyle
.
i_font_alpha
=
p_params
->
fontstyle
.
i_font_alpha
;
p_sys
->
b_updated
=
p_ovl
->
b_active
;
return
VLC_SUCCESS
;
}
static
int
exec_SetTextColor
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_results
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_ovl
->
fontstyle
.
i_font_color
=
p_params
->
fontstyle
.
i_font_color
;
p_sys
->
b_updated
=
p_ovl
->
b_active
;
return
VLC_SUCCESS
;
}
static
int
exec_SetTextSize
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_results
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_ovl
->
fontstyle
.
i_font_size
=
p_params
->
fontstyle
.
i_font_size
;
p_sys
->
b_updated
=
p_ovl
->
b_active
;
return
VLC_SUCCESS
;
}
static
int
exec_SetVisibility
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
(
void
)(
p_results
);
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
return
VLC_EGENERIC
;
p_ovl
->
b_active
=
p_params
->
b_visible
;
// ? VLC_FALSE : VLC_TRUE;
p_sys
->
b_updated
=
VLC_TRUE
;
return
VLC_SUCCESS
;
}
static
int
exec_StartAtomic
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandparams_t
*
p_results
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
(
void
)(
p_params
);
(
void
)(
p_results
);
p_sys
->
b_atomic
=
VLC_TRUE
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Command functions
*****************************************************************************/
static
commanddesc_t
p_commands
[]
=
{
{
.
psz_command
=
"DataSharedMem"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_DataSharedMem
,
.
pf_execute
=
exec_DataSharedMem
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"DeleteImage"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_Id
,
.
pf_execute
=
exec_DeleteImage
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"EndAtomic"
,
.
b_atomic
=
VLC_FALSE
,
.
pf_parser
=
parser_None
,
.
pf_execute
=
exec_EndAtomic
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"GenImage"
,
.
b_atomic
=
VLC_FALSE
,
.
pf_parser
=
parser_None
,
.
pf_execute
=
exec_GenImage
,
.
pf_unparse
=
unparse_GenImage
,
},
{
.
psz_command
=
"GetAlpha"
,
.
b_atomic
=
VLC_FALSE
,
.
pf_parser
=
parser_Id
,
.
pf_execute
=
exec_GetAlpha
,
.
pf_unparse
=
unparse_GetAlpha
,
},
{
.
psz_command
=
"GetPosition"
,
.
b_atomic
=
VLC_FALSE
,
.
pf_parser
=
parser_Id
,
.
pf_execute
=
exec_GetPosition
,
.
pf_unparse
=
unparse_GetPosition
,
},
{
.
psz_command
=
"GetTextAlpha"
,
.
b_atomic
=
VLC_FALSE
,
.
pf_parser
=
parser_Id
,
.
pf_execute
=
exec_GetTextAlpha
,
.
pf_unparse
=
unparse_GetTextAlpha
,
},
{
.
psz_command
=
"GetTextColor"
,
.
b_atomic
=
VLC_FALSE
,
.
pf_parser
=
parser_Id
,
.
pf_execute
=
exec_GetTextColor
,
.
pf_unparse
=
unparse_GetTextColor
,
},
{
.
psz_command
=
"GetTextSize"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_Id
,
.
pf_execute
=
exec_GetTextSize
,
.
pf_unparse
=
unparse_GetTextSize
,
},
{
.
psz_command
=
"GetVisibility"
,
.
b_atomic
=
VLC_FALSE
,
.
pf_parser
=
parser_Id
,
.
pf_execute
=
exec_GetVisibility
,
.
pf_unparse
=
unparse_GetVisibility
,
},
{
.
psz_command
=
"SetAlpha"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_SetAlpha
,
.
pf_execute
=
exec_SetAlpha
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"SetPosition"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_SetPosition
,
.
pf_execute
=
exec_SetPosition
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"SetTextAlpha"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_SetTextAlpha
,
.
pf_execute
=
exec_SetTextAlpha
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"SetTextColor"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_SetTextColor
,
.
pf_execute
=
exec_SetTextColor
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"SetTextSize"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_SetTextSize
,
.
pf_execute
=
exec_SetTextSize
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"SetVisibility"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_SetVisibility
,
.
pf_execute
=
exec_SetVisibility
,
.
pf_unparse
=
unparse_default
,
},
{
.
psz_command
=
"StartAtomic"
,
.
b_atomic
=
VLC_TRUE
,
.
pf_parser
=
parser_None
,
.
pf_execute
=
exec_StartAtomic
,
.
pf_unparse
=
unparse_default
,
}
};
void
RegisterCommand
(
filter_t
*
p_filter
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
size_t
i_index
=
0
;
p_sys
->
i_commands
=
ARRAY_SIZE
(
p_commands
);
p_sys
->
pp_commands
=
(
commanddesc_t
**
)
calloc
(
p_sys
->
i_commands
,
sizeof
(
commanddesc_t
*
)
);
if
(
!
p_sys
->
pp_commands
)
return
;
for
(
i_index
=
0
;
i_index
<
p_sys
->
i_commands
;
i_index
++
)
{
p_sys
->
pp_commands
[
i_index
]
=
(
commanddesc_t
*
)
malloc
(
sizeof
(
commanddesc_t
)
);
if
(
!
p_sys
->
pp_commands
[
i_index
]
)
return
;
p_sys
->
pp_commands
[
i_index
]
->
psz_command
=
strdup
(
p_commands
[
i_index
].
psz_command
);
p_sys
->
pp_commands
[
i_index
]
->
b_atomic
=
p_commands
[
i_index
].
b_atomic
;
p_sys
->
pp_commands
[
i_index
]
->
pf_parser
=
p_commands
[
i_index
].
pf_parser
;
p_sys
->
pp_commands
[
i_index
]
->
pf_execute
=
p_commands
[
i_index
].
pf_execute
;
p_sys
->
pp_commands
[
i_index
]
->
pf_unparse
=
p_commands
[
i_index
].
pf_unparse
;
}
msg_Dbg
(
p_filter
,
"%d commands are available"
,
p_sys
->
i_commands
);
for
(
size_t
i_index
=
0
;
i_index
<
p_sys
->
i_commands
;
i_index
++
)
msg_Dbg
(
p_filter
,
" %s"
,
p_sys
->
pp_commands
[
i_index
]
->
psz_command
);
}
void
UnregisterCommand
(
filter_t
*
p_filter
)
{
filter_sys_t
*
p_sys
=
(
filter_sys_t
*
)
p_filter
->
p_sys
;
size_t
i_index
=
0
;
for
(
i_index
=
0
;
i_index
<
p_sys
->
i_commands
;
i_index
++
)
{
free
(
p_sys
->
pp_commands
[
i_index
]
->
psz_command
);
free
(
p_sys
->
pp_commands
[
i_index
]
);
}
free
(
p_sys
->
pp_commands
);
p_sys
->
pp_commands
=
NULL
;
p_sys
->
i_commands
=
0
;
}
modules/video_filter/dynamicoverlay/dynamicoverlay_list.c
0 → 100644
View file @
1ac8441a
/*****************************************************************************
* dynamicoverlay_list.h : dynamic overlay list
*****************************************************************************
* Copyright (C) 2008 the VideoLAN team
* $Id$
*
* Author: Søren Bøg <avacore@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/vlc.h>
#include <vlc_osd.h>
#include <fcntl.h>
#include "dynamicoverlay.h"
/*****************************************************************************
* list_t: Command queue
*****************************************************************************/
int
ListInit
(
list_t
*
p_list
)
{
p_list
->
pp_head
=
malloc
(
16
*
sizeof
(
overlay_t
*
)
);
if
(
p_list
->
pp_head
==
NULL
)
return
VLC_ENOMEM
;
p_list
->
pp_tail
=
p_list
->
pp_head
+
16
;
memset
(
p_list
->
pp_head
,
0
,
16
*
sizeof
(
overlay_t
*
)
);
return
VLC_SUCCESS
;
}
int
ListDestroy
(
list_t
*
p_list
)
{
for
(
overlay_t
**
pp_cur
=
p_list
->
pp_head
;
pp_cur
<
p_list
->
pp_tail
;
++
pp_cur
)
{
if
(
*
pp_cur
!=
NULL
)
{
OverlayDestroy
(
*
pp_cur
);
free
(
*
pp_cur
);
}
}
free
(
p_list
->
pp_head
);
return
VLC_SUCCESS
;
}
ssize_t
ListAdd
(
list_t
*
p_list
,
overlay_t
*
p_new
)
{
/* Find an available slot */
for
(
overlay_t
**
pp_cur
=
p_list
->
pp_head
;
pp_cur
<
p_list
->
pp_tail
;
++
pp_cur
)
{
if
(
*
pp_cur
==
NULL
)
{
*
pp_cur
=
p_new
;
return
pp_cur
-
p_list
->
pp_head
;
}
}
/* Have to expand */
size_t
i_size
=
p_list
->
pp_tail
-
p_list
->
pp_head
;
size_t
i_newsize
=
i_size
*
2
;
p_list
->
pp_head
=
realloc
(
p_list
->
pp_head
,
i_newsize
*
sizeof
(
overlay_t
*
)
);
if
(
p_list
->
pp_head
==
NULL
)
return
VLC_ENOMEM
;
p_list
->
pp_tail
=
p_list
->
pp_head
+
i_newsize
;
memset
(
p_list
->
pp_head
+
i_size
,
0
,
i_size
*
sizeof
(
overlay_t
*
)
);
p_list
->
pp_head
[
i_size
]
=
p_new
;
return
i_size
;
}
int
ListRemove
(
list_t
*
p_list
,
size_t
i_idx
)
{
int
ret
;
if
(
(
i_idx
>=
(
size_t
)(
p_list
->
pp_tail
-
p_list
->
pp_head
)
)
||
(
p_list
->
pp_head
[
i_idx
]
==
NULL
)
)
{
return
VLC_EGENERIC
;
}
ret
=
OverlayDestroy
(
p_list
->
pp_head
[
i_idx
]
);
free
(
p_list
->
pp_head
[
i_idx
]
);
p_list
->
pp_head
[
i_idx
]
=
NULL
;
return
ret
;
}
overlay_t
*
ListGet
(
list_t
*
p_list
,
size_t
i_idx
)
{
if
(
(
i_idx
>=
(
size_t
)(
p_list
->
pp_tail
-
p_list
->
pp_head
)
)
||
(
p_list
->
pp_head
[
i_idx
]
==
NULL
)
)
{
return
NULL
;
}
return
p_list
->
pp_head
[
i_idx
];
}
overlay_t
*
ListWalk
(
list_t
*
p_list
)
{
static
overlay_t
**
pp_cur
=
NULL
;
if
(
pp_cur
==
NULL
)
pp_cur
=
p_list
->
pp_head
;
else
pp_cur
=
pp_cur
+
1
;
for
(
;
pp_cur
<
p_list
->
pp_tail
;
++
pp_cur
)
{
if
(
(
*
pp_cur
!=
NULL
)
&&
(
(
*
pp_cur
)
->
b_active
==
VLC_TRUE
)
&&
(
(
*
pp_cur
)
->
format
.
i_chroma
!=
VLC_FOURCC
(
'\0'
,
'\0'
,
'\0'
,
'\0'
)
)
)
{
return
*
pp_cur
;
}
}
pp_cur
=
NULL
;
return
NULL
;
}
modules/video_filter/dynamicoverlay/dynamicoverlay_queue.c
0 → 100644
View file @
1ac8441a
/*****************************************************************************
* dynamicoverlay_commands.c : dynamic overlay plugin commands
*****************************************************************************
* Copyright (C) 2008 the VideoLAN team
* $Id$
*
* Author: Søren Bøg <avacore@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/vlc.h>
#include <vlc_osd.h>
#include "dynamicoverlay.h"
/*****************************************************************************
* queue_t: Command queue
*****************************************************************************/
int
QueueInit
(
queue_t
*
p_queue
)
{
memset
(
p_queue
,
0
,
sizeof
(
queue_t
)
);
p_queue
->
p_head
=
NULL
;
p_queue
->
p_tail
=
NULL
;
return
VLC_SUCCESS
;
}
int
QueueDestroy
(
queue_t
*
p_queue
)
{
command_t
*
p_cur
=
p_queue
->
p_head
,
*
p_temp
;
while
(
p_cur
!=
NULL
)
{
p_temp
=
p_cur
;
p_cur
=
p_cur
->
p_next
;
free
(
p_temp
);
}
p_queue
->
p_head
=
NULL
;
p_queue
->
p_tail
=
NULL
;
return
VLC_SUCCESS
;
}
int
QueueEnqueue
(
queue_t
*
p_queue
,
command_t
*
p_cmd
)
{
if
(
p_queue
->
p_tail
!=
NULL
)
{
p_queue
->
p_tail
->
p_next
=
p_cmd
;
}
if
(
p_queue
->
p_head
==
NULL
)
{
p_queue
->
p_head
=
p_cmd
;
}
p_queue
->
p_tail
=
p_cmd
;
p_cmd
->
p_next
=
NULL
;
return
VLC_SUCCESS
;
}
command_t
*
QueueDequeue
(
queue_t
*
p_queue
)
{
if
(
p_queue
->
p_head
==
NULL
)
{
return
NULL
;
}
else
{
command_t
*
p_ret
=
p_queue
->
p_head
;
if
(
p_queue
->
p_head
==
p_queue
->
p_tail
)
{
p_queue
->
p_head
=
p_queue
->
p_tail
=
NULL
;
}
else
{
p_queue
->
p_head
=
p_queue
->
p_head
->
p_next
;
}
return
p_ret
;
}
}
int
QueueTransfer
(
queue_t
*
p_sink
,
queue_t
*
p_source
)
{
if
(
p_source
->
p_head
==
NULL
)
{
return
VLC_SUCCESS
;
}
if
(
p_sink
->
p_head
==
NULL
)
{
p_sink
->
p_head
=
p_source
->
p_head
;
p_sink
->
p_tail
=
p_source
->
p_tail
;
}
else
{
p_sink
->
p_tail
->
p_next
=
p_source
->
p_head
;
p_sink
->
p_tail
=
p_source
->
p_tail
;
}
p_source
->
p_head
=
p_source
->
p_tail
=
NULL
;
return
VLC_SUCCESS
;
}
modules/video_filter/osdmenu.c
View file @
1ac8441a
...
...
@@ -435,6 +435,7 @@ static subpicture_region_t *create_picture_region( filter_t *p_filter, subpictur
p_region
->
i_x
=
0
;
p_region
->
i_y
=
0
;
p_region
->
i_align
=
p_filter
->
p_sys
->
i_position
;
p_region
->
i_alpha
=
p_filter
->
p_sys
->
i_alpha
;
#if 0
msg_Dbg( p_filter, "SPU picture region position (%d,%d) (%d,%d) [%p]",
p_region->i_x, p_region->i_y,
...
...
src/video_output/vout_subpictures.c
View file @
1ac8441a
...
...
@@ -291,6 +291,7 @@ subpicture_region_t *__spu_CreateRegion( vlc_object_t *p_this,
if
(
!
p_region
)
return
NULL
;
memset
(
p_region
,
0
,
sizeof
(
subpicture_region_t
)
);
p_region
->
i_alpha
=
0xff
;
p_region
->
p_next
=
NULL
;
p_region
->
p_cache
=
NULL
;
p_region
->
fmt
=
*
p_fmt
;
...
...
@@ -336,6 +337,7 @@ subpicture_region_t *__spu_MakeRegion( vlc_object_t *p_this,
(
void
)
p_this
;
if
(
!
p_region
)
return
NULL
;
memset
(
p_region
,
0
,
sizeof
(
subpicture_region_t
)
);
p_region
->
i_alpha
=
0xff
;
p_region
->
p_next
=
0
;
p_region
->
p_cache
=
0
;
p_region
->
fmt
=
*
p_fmt
;
...
...
@@ -901,6 +903,7 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt,
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
=
p_spu
->
p_scale
->
pf_video_filter
(
p_spu
->
p_scale
,
&
p_region
->
p_cache
->
picture
);
...
...
@@ -1060,7 +1063,7 @@ void spu_RenderSubpictures( spu_t *p_spu, video_format_t *p_fmt,
{
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
/
25
5
);
i_fade_alpha
*
p_subpic
->
i_alpha
*
p_region
->
i_alpha
/
6502
5
);
}
else
{
...
...
test/dynamicoverlay/Makefile
0 → 100644
View file @
1ac8441a
all
:
overlay-test
overlay-test
:
overlay-test.c
gcc
-g2
--std
=
c99
-D_XOPEN_SOURCE
=
500 overlay-test.c
-lm
-o
overlay-test
test/dynamicoverlay/overlay-test.c
0 → 100644
View file @
1ac8441a
/*****************************************************************************
* overlay-test.c : test program for the dynamic overlay plugin
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Author: Søren Bøg <avacore@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <math.h>
#include <sys/fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
/*****************************************************************************
* Images
*****************************************************************************/
#define WIDTH 128
#define HEIGHT 128
#define TEXT "Hello world!"
#define TEXTSIZE sizeof( TEXT )
char
*
p_imageRGBA
;
char
*
p_text
;
void
DataCreate
(
void
)
{
char
*
p_data
=
p_imageRGBA
;
for
(
size_t
i
=
0
;
i
<
HEIGHT
;
++
i
)
{
for
(
size_t
j
=
0
;
j
<
HEIGHT
;
++
j
)
{
*
(
p_data
++
)
=
i
*
4
&
0xFF
;
*
(
p_data
++
)
=
0xFF
;
*
(
p_data
++
)
=
0x00
;
*
(
p_data
++
)
=
j
*
4
&
0xFF
;
}
}
memcpy
(
p_text
,
TEXT
,
TEXTSIZE
);
}
/*****************************************************************************
* I/O Helpers
*****************************************************************************/
int
IsFailure
(
char
*
psz_text
)
{
return
strncmp
(
psz_text
,
"SUCCESS:"
,
8
);
}
void
CheckResult
(
FILE
*
p_res
)
{
char
psz_resp
[
9
];
fscanf
(
p_res
,
"%8s"
,
&
psz_resp
);
if
(
IsFailure
(
psz_resp
)
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
}
void
CheckedCommand
(
FILE
*
p_cmd
,
FILE
*
p_res
,
char
*
p_format
,
...
)
{
va_list
ap
;
va_start
(
ap
,
p_format
);
vfprintf
(
p_cmd
,
p_format
,
ap
);
fflush
(
p_cmd
);
if
(
p_res
!=
NULL
)
{
CheckResult
(
p_res
);
}
va_end
(
ap
);
}
int
GenImage
(
FILE
*
p_cmd
,
FILE
*
p_res
)
{
int
i_overlay
;
printf
(
"Getting an overlay..."
);
CheckedCommand
(
p_cmd
,
p_res
,
"GenImage
\n
"
);
fscanf
(
p_res
,
"%d"
,
&
i_overlay
);
printf
(
" done. Overlay is %d
\n
"
,
i_overlay
);
return
i_overlay
;
}
void
DeleteImage
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
)
{
printf
(
"Removing image..."
);
CheckedCommand
(
p_cmd
,
p_res
,
"DeleteImage %d
\n
"
,
i_overlay
);
printf
(
" done
\n
"
);
}
void
StartAtomic
(
FILE
*
p_cmd
,
FILE
*
p_res
)
{
CheckedCommand
(
p_cmd
,
p_res
,
"StartAtomic
\n
"
);
}
void
EndAtomic
(
FILE
*
p_cmd
,
FILE
*
p_res
)
{
CheckedCommand
(
p_cmd
,
p_res
,
"EndAtomic
\n
"
);
}
void
DataSharedMem
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
,
int
i_width
,
int
i_height
,
char
*
psz_format
,
int
i_shmid
)
{
printf
(
"Sending data via shared memory..."
);
CheckedCommand
(
p_cmd
,
p_res
,
"DataSharedMem %d %d %d %s %d
\n
"
,
i_overlay
,
i_width
,
i_height
,
psz_format
,
i_shmid
);
printf
(
" done
\n
"
);
}
void
SetAlpha
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
,
int
i_alpha
)
{
CheckedCommand
(
p_cmd
,
p_res
,
"SetAlpha %d %d
\n
"
,
i_overlay
,
i_alpha
);
}
void
SetPosition
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
,
int
i_x
,
int
i_y
)
{
CheckedCommand
(
p_cmd
,
p_res
,
"SetPosition %d %d %d
\n
"
,
i_overlay
,
i_x
,
i_y
);
}
void
SetVisibility
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
,
int
i_visible
)
{
CheckedCommand
(
p_cmd
,
p_res
,
"SetVisibility %d %d
\n
"
,
i_overlay
,
i_visible
);
}
void
SetTextAlpha
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
,
int
i_alpha
)
{
CheckedCommand
(
p_cmd
,
p_res
,
"SetTextAlpha %d %d
\n
"
,
i_overlay
,
i_alpha
);
}
void
SetTextColor
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
,
int
i_red
,
int
i_green
,
int
i_blue
)
{
CheckedCommand
(
p_cmd
,
p_res
,
"SetTextColor %d %d %d %d
\n
"
,
i_overlay
,
i_red
,
i_green
,
i_blue
);
}
void
SetTextSize
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
,
int
i_size
)
{
CheckedCommand
(
p_cmd
,
p_res
,
"SetTextSize %d %d
\n
"
,
i_overlay
,
i_size
);
}
int
GetTextSize
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
)
{
int
i_size
;
CheckedCommand
(
p_cmd
,
p_res
,
"GetTextSize %d
\n
"
,
i_overlay
);
fscanf
(
p_res
,
"%d"
,
&
i_size
);
return
i_size
;
}
/*****************************************************************************
* Test Routines
*****************************************************************************/
void
BasicTest
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
)
{
printf
(
"Activating overlay..."
);
SetVisibility
(
p_cmd
,
p_res
,
i_overlay
,
1
);
printf
(
" done
\n
"
);
printf
(
"Sweeping alpha..."
);
for
(
int
i_alpha
=
0xFF
;
i_alpha
>=
-
0xFF
;
i_alpha
-=
8
)
{
SetAlpha
(
p_cmd
,
p_res
,
i_overlay
,
abs
(
i_alpha
)
);
usleep
(
20000
);
}
SetAlpha
(
p_cmd
,
p_res
,
i_overlay
,
255
);
printf
(
" done
\n
"
);
printf
(
"Circle motion..."
);
for
(
float
f_theta
=
0
;
f_theta
<=
2
*
M_PI
;
f_theta
+=
M_PI
/
64
.
0
)
{
SetPosition
(
p_cmd
,
p_res
,
i_overlay
,
(
int
)(
-
cos
(
f_theta
)
*
100
.
0
+
100
.
0
),
(
int
)(
-
sin
(
f_theta
)
*
100
.
0
+
100
.
0
)
);
usleep
(
20000
);
}
SetPosition
(
p_cmd
,
p_res
,
i_overlay
,
0
,
100
);
printf
(
" done
\n
"
);
printf
(
"Atomic motion..."
);
StartAtomic
(
p_cmd
,
p_res
);
SetPosition
(
p_cmd
,
NULL
,
i_overlay
,
200
,
50
);
sleep
(
1
);
SetPosition
(
p_cmd
,
NULL
,
i_overlay
,
0
,
0
);
EndAtomic
(
p_cmd
,
p_res
);
CheckResult
(
p_res
);
CheckResult
(
p_res
);
printf
(
" done
\n
"
);
sleep
(
5
);
}
void
TextTest
(
FILE
*
p_cmd
,
FILE
*
p_res
,
int
i_overlay
)
{
printf
(
"Sweeping (text) alpha..."
);
for
(
int
i_alpha
=
0xFF
;
i_alpha
>=
-
0xFF
;
i_alpha
-=
8
)
{
SetTextAlpha
(
p_cmd
,
p_res
,
i_overlay
,
abs
(
i_alpha
)
);
usleep
(
20000
);
}
SetTextAlpha
(
p_cmd
,
p_res
,
i_overlay
,
255
);
printf
(
" done
\n
"
);
printf
(
"Sweeping colors..."
);
for
(
int
i_red
=
0xFF
;
i_red
>=
0x00
;
i_red
-=
8
)
{
SetTextColor
(
p_cmd
,
p_res
,
i_overlay
,
i_red
,
0xFF
,
0xFF
);
usleep
(
20000
);
}
for
(
int
i_green
=
0xFF
;
i_green
>=
0x00
;
i_green
-=
8
)
{
SetTextColor
(
p_cmd
,
p_res
,
i_overlay
,
0x00
,
i_green
,
0xFF
);
usleep
(
20000
);
}
for
(
int
i_blue
=
0xFF
;
i_blue
>=
0x00
;
i_blue
-=
8
)
{
SetTextColor
(
p_cmd
,
p_res
,
i_overlay
,
0x00
,
0x00
,
i_blue
);
usleep
(
20000
);
}
SetTextColor
(
p_cmd
,
p_res
,
i_overlay
,
0x00
,
0x00
,
0x00
);
printf
(
" done
\n
"
);
printf
(
"Getting size..."
);
int
i_basesize
=
GetTextSize
(
p_cmd
,
p_res
,
i_overlay
);
printf
(
" done. Size is %d
\n
"
,
i_basesize
);
printf
(
"Sweeping size..."
);
for
(
float
f_theta
=
0
;
f_theta
<=
M_PI
;
f_theta
+=
M_PI
/
128
.
0
)
{
SetTextSize
(
p_cmd
,
p_res
,
i_overlay
,
i_basesize
*
(
1
+
3
*
sin
(
f_theta
)
)
);
usleep
(
20000
);
}
SetTextSize
(
p_cmd
,
p_res
,
i_overlay
,
i_basesize
);
printf
(
" done
\n
"
);
sleep
(
5
);
}
/*****************************************************************************
* main
*****************************************************************************/
int
main
(
int
i_argc
,
char
*
ppsz_argv
[]
)
{
if
(
i_argc
!=
3
)
{
printf
(
"Incorrect number of parameters.
\n
"
"Usage is: %s command-fifo response-fifo
\n
"
,
ppsz_argv
[
0
]
);
exit
(
-
2
);
}
printf
(
"Creating shared memory for RGBA..."
);
int
i_shmRGBA
=
shmget
(
IPC_PRIVATE
,
WIDTH
*
HEIGHT
*
4
,
S_IRWXU
);
if
(
i_shmRGBA
==
-
1
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" done, ID is %d. Text..."
,
i_shmRGBA
);
int
i_shmText
=
shmget
(
IPC_PRIVATE
,
TEXTSIZE
,
S_IRWXU
);
if
(
i_shmText
==
-
1
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" done, ID is %d
\n
"
,
i_shmText
);
printf
(
"Attaching shared memory for RGBA..."
);
p_imageRGBA
=
shmat
(
i_shmRGBA
,
NULL
,
0
);
if
(
p_imageRGBA
==
(
void
*
)
-
1
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" done. Text..."
);
p_text
=
shmat
(
i_shmText
,
NULL
,
0
);
if
(
p_text
==
(
void
*
)
-
1
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" done
\n
"
);
printf
(
"Queueing shared memory for destruction, RGBA..."
);
if
(
shmctl
(
i_shmRGBA
,
IPC_RMID
,
0
)
==
-
1
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" done. Text..."
);
if
(
shmctl
(
i_shmText
,
IPC_RMID
,
0
)
==
-
1
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" done
\n
"
);
printf
(
"Generating data..."
);
DataCreate
();
printf
(
" done
\n
"
);
printf
(
"Making FIFOs..."
);
if
(
mkfifo
(
ppsz_argv
[
1
],
S_IRWXU
)
)
{
if
(
errno
!=
EEXIST
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" input already exists..."
);
}
if
(
mkfifo
(
ppsz_argv
[
2
],
S_IRWXU
)
)
{
if
(
errno
!=
EEXIST
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" output already exists..."
);
}
printf
(
" done
\n
"
);
printf
(
"Please make sure vlc is running.
\n
"
"You should append parameters similar to the following:
\n
"
"--sub-filter overlay{input=%s,output=%s}
\n
"
,
ppsz_argv
[
1
],
ppsz_argv
[
2
]
);
printf
(
"Opening FIFOs..."
);
FILE
*
p_cmd
=
fopen
(
ppsz_argv
[
1
],
"w"
);
if
(
p_cmd
==
NULL
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
FILE
*
p_res
=
fopen
(
ppsz_argv
[
2
],
"r"
);
if
(
p_res
==
NULL
)
{
printf
(
" failed
\n
"
);
exit
(
-
1
);
}
printf
(
" done
\n
"
);
int
i_overlay_image
=
GenImage
(
p_cmd
,
p_res
);
int
i_overlay_text
=
GenImage
(
p_cmd
,
p_res
);
DataSharedMem
(
p_cmd
,
p_res
,
i_overlay_image
,
WIDTH
,
HEIGHT
,
"RGBA"
,
i_shmRGBA
);
DataSharedMem
(
p_cmd
,
p_res
,
i_overlay_text
,
TEXTSIZE
,
1
,
"TEXT"
,
i_shmText
);
BasicTest
(
p_cmd
,
p_res
,
i_overlay_image
);
BasicTest
(
p_cmd
,
p_res
,
i_overlay_text
);
TextTest
(
p_cmd
,
p_res
,
i_overlay_text
);
DeleteImage
(
p_cmd
,
p_res
,
i_overlay_image
);
DeleteImage
(
p_cmd
,
p_res
,
i_overlay_text
);
}
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