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
5f65eb66
Commit
5f65eb66
authored
Mar 01, 2008
by
Jean-Paul Saman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor dynamic overlays from Google Summer of Code project.
parent
f1dd920e
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1334 additions
and
0 deletions
+1334
-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
+706
-0
modules/video_filter/dynamicoverlay/dynamicoverlay.h
modules/video_filter/dynamicoverlay/dynamicoverlay.h
+128
-0
modules/video_filter/dynamicoverlay/dynamicoverlay_buffer.c
modules/video_filter/dynamicoverlay/dynamicoverlay_buffer.c
+142
-0
modules/video_filter/dynamicoverlay/dynamicoverlay_commands.h
...les/video_filter/dynamicoverlay/dynamicoverlay_commands.h
+242
-0
modules/video_filter/dynamicoverlay/dynamicoverlay_queue.c
modules/video_filter/dynamicoverlay/dynamicoverlay_queue.c
+114
-0
No files found.
modules/video_filter/dynamicoverlay/Modules.am
0 → 100644
View file @
5f65eb66
SOURCES_dynamicoverlay = dynamicoverlay.c dynamicoverlay_buffer.c dynamicoverlay_queue.c
noinst_HEADERS = dynamicoverlay.h dynamicoverlay_commands.h
modules/video_filter/dynamicoverlay/dynamicoverlay.c
0 → 100644
View file @
5f65eb66
/*****************************************************************************
* 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 <fcntl.h>
#include <vlc/vlc.h>
#include <vlc_sout.h>
#include <vlc_vout.h>
#include <vlc_filter.h>
#include <vlc_osd.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
};
/*****************************************************************************
* overlay_t: Overlay descriptor
*****************************************************************************/
struct
overlay_t
{
int
i_x
,
i_y
;
int
i_alpha
;
vlc_bool_t
b_active
;
video_format_t
format
;
union
{
picture_t
*
p_pic
;
char
*
p_text
;
}
data
;
};
typedef
struct
overlay_t
overlay_t
;
static
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
);
p_ovl
->
data
.
p_text
=
NULL
;
return
p_ovl
;
}
static
int
OverlayDestroy
(
overlay_t
*
p_ovl
)
{
if
(
p_ovl
->
data
.
p_text
!=
NULL
)
free
(
p_ovl
->
data
.
p_text
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* list_t: Command queue
*****************************************************************************/
struct
list_t
{
overlay_t
**
pp_head
,
**
pp_tail
;
};
typedef
struct
list_t
list_t
;
static
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
;
}
static
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
;
}
static
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
;
}
static
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
;
}
static
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
];
}
static
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
;
}
/*****************************************************************************
* 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
;
vlc_bool_t
b_updated
,
b_atomic
;
queue_t
atomic
,
pending
,
processed
;
list_t
overlays
;
};
/*****************************************************************************
* Command functions
*****************************************************************************/
#define SKIP \
{ \
const char *psz_temp = psz_command; \
while( isspace( *psz_temp ) ) { \
++psz_temp; \
} \
if( psz_temp == psz_command ) { \
return VLC_EGENERIC; \
} \
psz_command = psz_temp; \
}
#define INT( name ) \
SKIP \
{ \
char *psz_temp; \
p_myparams->name = strtol( psz_command, &psz_temp, 10 ); \
if( psz_temp == psz_command ) \
{ \
return VLC_EGENERIC; \
} \
psz_command = psz_temp; \
}
#define CHARS( name, count ) \
SKIP \
{ \
if( psz_end - psz_command < count ) \
{ \
return VLC_EGENERIC; \
} \
memcpy( p_myparams->name, psz_command, count ); \
psz_command += count; \
}
#define COMMAND( name, param, ret, atomic, code ) \
static int Command##name##Parse( const char *psz_command, \
const char *psz_end, \
commandparams_t *p_params ) \
{ \
struct commandparams##name##_t *p_myparams = &p_params->name; \
param \
return VLC_SUCCESS; \
}
#include "dynamicoverlay_commands.h"
#undef COMMAND
#undef SKIP
#undef INT
#undef CHARS
#define COMMAND( name, param, ret, atomic, code ) \
static int Command##name##Exec( filter_t *p_filter, \
const commandparams_t *p_gparams, \
commandresults_t *p_gresults, \
filter_sys_t *p_sys ) \
{ \
const struct commandparams##name##_t *p_params = &p_gparams->name; \
struct commandresults##name##_t *p_results = &p_gresults->name; \
code \
}
#include "dynamicoverlay_commands.h"
#undef COMMAND
#define INT( name ) \
{ \
int ret = BufferPrintf( p_output, " %d", p_myresults->name ); \
if( ret != VLC_SUCCESS ) { \
return ret; \
} \
}
#define CHARS( name, count ) \
{ \
int ret = BufferAdd( p_output, p_myresults->name, count ); \
if( ret != VLC_SUCCESS ) { \
return ret; \
} \
}
#define COMMAND( name, param, ret, atomic, code ) \
static int Command##name##Unparse( const commandresults_t *p_results, \
buffer_t *p_output ) \
{ \
const struct commandresults##name##_t *p_myresults = &p_results->name; \
ret \
return VLC_SUCCESS; \
}
#include "dynamicoverlay_commands.h"
#undef COMMAND
#undef INT
#undef CHARS
static
commanddesc_t
p_commands
[]
=
{
#define COMMAND( name, param, ret, atomic, code ) \
{ #name, atomic, Command##name##Parse, Command##name##Exec, Command##name##Unparse },
#include "dynamicoverlay_commands.h"
#undef COMMAND
};
#define NUMCOMMANDS (sizeof(p_commands)/sizeof(commanddesc_t))
/*****************************************************************************
* 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
);
msg_Dbg
(
p_filter
,
"%d commands are available:"
,
NUMCOMMANDS
);
for
(
size_t
i_index
=
0
;
i_index
<
NUMCOMMANDS
;
++
i_index
)
msg_Dbg
(
p_filter
,
" %s"
,
p_commands
[
i_index
].
psz_command
);
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
);
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
)
)
)
{
*
p_end
=
'\0'
;
p_cmd
=
p_sys
->
input
.
p_begin
;
commanddesc_t
*
p_lower
=
p_commands
;
commanddesc_t
*
p_upper
=
p_commands
+
NUMCOMMANDS
;
size_t
i_index
=
0
;
while
(
1
)
{
if
(
(
p_cmd
[
i_index
]
==
'\0'
)
||
isspace
(
p_cmd
[
i_index
]
)
)
{
break
;
}
commanddesc_t
*
p_cur
=
p_lower
;
while
(
(
p_cur
<
p_upper
)
&&
(
p_cur
->
psz_command
[
i_index
]
!=
p_cmd
[
i_index
]
)
)
{
++
p_cur
;
}
p_lower
=
p_cur
;
while
(
(
p_cur
<
p_upper
)
&&
(
p_cur
->
psz_command
[
i_index
]
==
p_cmd
[
i_index
]
)
)
{
++
p_cur
;
}
p_upper
=
p_cur
;
++
i_index
;
}
if
(
p_lower
>=
p_upper
)
{
/* No matching command */
p_cmd
[
i_index
]
=
'\0'
;
msg_Err
(
p_filter
,
"Got invalid command: %s"
,
p_cmd
);
BufferPrintf
(
&
p_sys
->
output
,
"FAILURE: %d Invalid Command
\n
"
,
VLC_EGENERIC
);
}
else
if
(
p_lower
+
1
<
p_upper
)
{
/* Command is not a unique prefix of a command */
p_cmd
[
i_index
]
=
'\0'
;
msg_Err
(
p_filter
,
"Got ambiguous command: %s"
,
p_cmd
);
msg_Err
(
p_filter
,
"Possible completions are:"
);
for
(
;
p_lower
<
p_upper
;
++
p_lower
)
{
msg_Err
(
p_filter
,
" %s"
,
p_lower
->
psz_command
);
}
BufferPrintf
(
&
p_sys
->
output
,
"FAILURE: %d Invalid Command
\n
"
,
VLC_EGENERIC
);
}
else
{
/* Command is valid */
command_t
*
p_command
=
malloc
(
sizeof
(
command_t
)
);
if
(
!
p_command
)
return
NULL
;
p_command
->
p_command
=
p_lower
;
p_command
->
p_command
->
pf_parser
(
p_cmd
+
i_index
,
p_end
,
&
p_command
->
params
);
if
(
(
p_command
->
p_command
->
b_atomic
==
VLC_TRUE
)
&&
(
p_sys
->
b_atomic
==
VLC_TRUE
)
)
QueueEnqueue
(
&
p_sys
->
atomic
,
p_command
);
else
QueueEnqueue
(
&
p_sys
->
pending
,
p_command
);
p_cmd
[
i_index
]
=
'\0'
;
msg_Dbg
(
p_filter
,
"Got valid command: %s"
,
p_cmd
);
}
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
,
p_sys
);
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_unparser
(
&
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"
,
&
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
(
p_filter
,
&
p_overlay
->
format
);
if
(
!*
pp_region
)
{
msg_Err
(
p_filter
,
"cannot allocate subpicture region"
);
continue
;
}
(
*
pp_region
)
->
psz_text
=
strdup
(
p_overlay
->
data
.
p_text
);
}
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
(
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
(
psz_var
);
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
newval
);
return
VLC_EGENERIC
;
}
modules/video_filter/dynamicoverlay/dynamicoverlay.h
0 → 100644
View file @
5f65eb66
/*****************************************************************************
* 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
/*****************************************************************************
* 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
);
/*****************************************************************************
* Command structures
*****************************************************************************/
#define INT( name ) int name;
#define CHARS( name, count ) char name[count];
#define COMMAND( name, param, ret, atomic, code ) \
struct commandparams##name##_t \
{ \
param \
};
#include "dynamicoverlay_commands.h"
#undef COMMAND
#undef INT
#undef CHARS
union
commandparams_t
{
#define COMMAND( name, param, ret, atomic, code ) struct commandparams##name##_t name;
#include "dynamicoverlay_commands.h"
#undef COMMAND
};
typedef
union
commandparams_t
commandparams_t
;
#define INT( name ) int name;
#define CHARS( name, count ) char name[count];
#define COMMAND( name, param, ret, atomic, code ) \
struct commandresults##name##_t \
{ \
ret \
};
#include "dynamicoverlay_commands.h"
#undef COMMAND
#undef INT
#undef CHARS
union
commandresults_t
{
#define COMMAND( name, param, ret, atomic, code ) struct commandresults##name##_t name;
#include "dynamicoverlay_commands.h"
#undef COMMAND
};
typedef
union
commandresults_t
commandresults_t
;
typedef
struct
commanddesc_t
{
const
char
*
psz_command
;
vlc_bool_t
b_atomic
;
int
(
*
pf_parser
)
(
const
char
*
psz_command
,
const
char
*
psz_end
,
commandparams_t
*
p_params
);
int
(
*
pf_execute
)
(
filter_t
*
p_filter
,
const
commandparams_t
*
p_params
,
commandresults_t
*
p_results
,
struct
filter_sys_t
*
p_sys
);
int
(
*
pf_unparser
)
(
const
commandresults_t
*
p_results
,
buffer_t
*
p_output
);
}
commanddesc_t
;
typedef
struct
command_t
{
struct
commanddesc_t
*
p_command
;
int
i_status
;
commandparams_t
params
;
commandresults_t
results
;
struct
command_t
*
p_next
;
}
command_t
;
/*****************************************************************************
* 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
);
#endif
modules/video_filter/dynamicoverlay/dynamicoverlay_buffer.c
0 → 100644
View file @
5f65eb66
/*****************************************************************************
* dynamicoverlay_commands.def : 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 "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
;
}
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.h
0 → 100644
View file @
5f65eb66
/*****************************************************************************
* dynamicoverlay_commands.def : 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.
*****************************************************************************/
#include <sys/shm.h>
/* Commands must be sorted alphabetically.
I haven't found out how to implement quick sort in cpp */
COMMAND
(
DataSharedMem
,
INT
(
i_id
)
INT
(
i_width
)
INT
(
i_height
)
CHARS
(
p_fourcc
,
4
)
INT
(
i_shmid
),
,
VLC_TRUE
,
{
overlay_t
*
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
;
}
struct
shmid_ds
shminfo
;
if
(
shmctl
(
p_params
->
i_shmid
,
IPC_STAT
,
&
shminfo
)
==
-
1
)
{
msg_Err
(
p_filter
,
"Unable to access shared memory"
);
return
VLC_EGENERIC
;
}
size_t
i_size
=
shminfo
.
shm_segsz
;
if
(
strncmp
(
p_params
->
p_fourcc
,
"TEXT"
,
4
)
==
0
)
{
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
(
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
);
char
*
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
{
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
,
VLC_FOURCC
(
p_params
->
p_fourcc
[
0
],
p_params
->
p_fourcc
[
1
],
p_params
->
p_fourcc
[
2
],
p_params
->
p_fourcc
[
3
]
),
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
;
}
size_t
i_neededsize
=
0
;
for
(
size_t
i_plane
=
0
;
i_plane
<
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
;
}
char
*
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
;
}
char
*
p_in
=
p_data
;
for
(
size_t
i_plane
=
0
;
i_plane
<
p_ovl
->
data
.
p_pic
->
i_planes
;
++
i_plane
)
{
char
*
p_out
=
p_ovl
->
data
.
p_pic
->
p
[
i_plane
].
p_pixels
;
for
(
size_t
i_line
=
0
;
i_line
<
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
;
}
)
COMMAND
(
DeleteImage
,
INT
(
i_id
),
,
VLC_TRUE
,
{
p_sys
->
b_updated
=
VLC_TRUE
;
return
ListRemove
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
}
)
COMMAND
(
EndAtomic
,
,
,
VLC_FALSE
,
{
QueueTransfer
(
&
p_sys
->
pending
,
&
p_sys
->
atomic
);
p_sys
->
b_atomic
=
VLC_FALSE
;
return
VLC_SUCCESS
;
}
)
COMMAND
(
GenImage
,
,
INT
(
i_newid
),
VLC_FALSE
,
{
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_newid
=
i_idx
;
return
VLC_SUCCESS
;
}
)
COMMAND
(
GetAlpha
,
INT
(
i_id
),
INT
(
i_alpha
),
VLC_FALSE
,
{
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
;
}
)
COMMAND
(
GetPosition
,
INT
(
i_id
),
INT
(
i_x
)
INT
(
i_y
),
VLC_FALSE
,
{
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
;
}
)
COMMAND
(
GetVisibility
,
INT
(
i_id
),
INT
(
i_vis
),
VLC_FALSE
,
{
overlay_t
*
p_ovl
=
ListGet
(
&
p_sys
->
overlays
,
p_params
->
i_id
);
if
(
p_ovl
==
NULL
)
{
return
VLC_EGENERIC
;
}
p_results
->
i_vis
=
(
p_ovl
->
b_active
==
VLC_TRUE
)
?
1
:
0
;
return
VLC_SUCCESS
;
}
)
COMMAND
(
SetAlpha
,
INT
(
i_id
)
INT
(
i_alpha
),
,
VLC_TRUE
,
{
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
;
}
)
COMMAND
(
SetPosition
,
INT
(
i_id
)
INT
(
i_x
)
INT
(
i_y
),
,
VLC_TRUE
,
{
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
;
}
)
COMMAND
(
SetVisibility
,
INT
(
i_id
)
INT
(
i_vis
),
,
VLC_TRUE
,
{
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
->
i_vis
==
0
)
?
VLC_FALSE
:
VLC_TRUE
;
p_sys
->
b_updated
=
VLC_TRUE
;
return
VLC_SUCCESS
;
}
)
COMMAND
(
StartAtomic
,
,
,
VLC_FALSE
,
{
p_sys
->
b_atomic
=
VLC_TRUE
;
return
VLC_SUCCESS
;
}
)
modules/video_filter/dynamicoverlay/dynamicoverlay_queue.c
0 → 100644
View file @
5f65eb66
/*****************************************************************************
* 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 "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
;
}
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