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
f976d6ae
Commit
f976d6ae
authored
Apr 15, 2005
by
Christophe Massiot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* ALL: converted the video output module "picture" to a stream output
module "mosaic-bridge".
parent
0ae97f35
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
625 additions
and
133 deletions
+625
-133
configure.ac
configure.ac
+3
-3
modules/stream_out/Modules.am
modules/stream_out/Modules.am
+1
-0
modules/stream_out/bridge.c
modules/stream_out/bridge.c
+10
-18
modules/stream_out/mosaic_bridge.c
modules/stream_out/mosaic_bridge.c
+512
-0
modules/video_filter/Modules.am
modules/video_filter/Modules.am
+1
-1
modules/video_filter/mosaic.c
modules/video_filter/mosaic.c
+69
-94
modules/video_filter/mosaic.h
modules/video_filter/mosaic.h
+29
-15
modules/video_output/Modules.am
modules/video_output/Modules.am
+0
-2
No files found.
configure.ac
View file @
f976d6ae
...
...
@@ -986,7 +986,7 @@ if test "${SYS}" != "mingwce"; then
VLC_ADD_PLUGINS([externrun])
VLC_ADD_PLUGINS([access_fake access_filter_timeshift])
VLC_ADD_PLUGINS([gestures rc telnet hotkeys netsync showintf time marq sap shout])
VLC_ADD_PLUGINS([
picture
mosaic wall motiondetect clone crop])
VLC_ADD_PLUGINS([mosaic wall motiondetect clone crop])
VLC_ADD_PLUGINS([i420_yuy2 i422_yuy2 i420_ymga])
VLC_ADD_PLUGINS([aout_file linear_resampler bandlimited_resampler])
VLC_ADD_PLUGINS([float32_mixer spdif_mixer simple_channel_mixer])
...
...
@@ -1227,7 +1227,7 @@ then
VLC_ADD_PLUGINS([packetizer_copy])
VLC_ADD_PLUGINS([stream_out_dummy stream_out_standard stream_out_es stream_out_rtp stream_out_description vod_rtsp])
VLC_ADD_PLUGINS([stream_out_duplicate stream_out_gather stream_out_display stream_out_transcode stream_out_bridge])
VLC_ADD_PLUGINS([stream_out_duplicate stream_out_gather stream_out_display stream_out_transcode stream_out_bridge
stream_out_mosaic_bridge
])
# VLC_ADD_PLUGINS([stream_out_transrate])
AC_DEFINE(ENABLE_SOUT, 1, Define if you want the stream output support)
...
...
@@ -2533,7 +2533,7 @@ AC_ARG_ENABLE(speex,
if test "${enable_speex}" != "no"
then
AC_CHECK_HEADERS(speex/speex.h, [
LDFLAGS="${LDFLAGS_save} ${LDFLAGS_
toolame
}"
LDFLAGS="${LDFLAGS_save} ${LDFLAGS_
speex
}"
AC_CHECK_LIB(speex, speex_decode_int, [
VLC_ADD_PLUGINS([speex])
VLC_ADD_LDFLAGS([speex],[-lspeex]) ],
...
...
modules/stream_out/Modules.am
View file @
f976d6ae
...
...
@@ -11,3 +11,4 @@ SOURCES_stream_out_gather = gather.c
SOURCES_stream_out_rtp = rtp.c
SOURCES_stream_out_switcher = switcher.c
SOURCES_stream_out_bridge = bridge.c
SOURCES_stream_out_mosaic_bridge = mosaic_bridge.c
modules/stream_out/bridge.c
View file @
f976d6ae
...
...
@@ -58,7 +58,7 @@ vlc_module_begin();
set_shortname
(
_
(
"Bridge"
));
set_description
(
_
(
"Bridge stream output"
));
add_submodule
();
set_section
(
N_
(
"Bridge out"
),
NULL
);
set_section
(
N_
(
"Bridge out"
),
NULL
);
set_capability
(
"sout stream"
,
50
);
add_shortcut
(
"bridge-out"
);
/* Only usable with VLM. No category so not in gui preferences
...
...
@@ -69,12 +69,12 @@ vlc_module_begin();
set_callbacks
(
OpenOut
,
CloseOut
);
add_submodule
();
set_section
(
N_
(
"Bridge in"
),
NULL
);
set_section
(
N_
(
"Bridge in"
),
NULL
);
set_capability
(
"sout stream"
,
50
);
add_shortcut
(
"bridge-in"
);
/*set_category( CAT_SOUT );
set_subcategory( SUBCAT_SOUT_STREAM );*/
add_integer
(
SOUT_CFG_PREFIX_IN
"delay"
,
10
0
,
NULL
,
DELAY_TEXT
,
add_integer
(
SOUT_CFG_PREFIX_IN
"delay"
,
0
,
NULL
,
DELAY_TEXT
,
DELAY_LONGTEXT
,
VLC_FALSE
);
add_integer
(
SOUT_CFG_PREFIX_IN
"id-offset"
,
8192
,
NULL
,
ID_OFFSET_TEXT
,
ID_OFFSET_LONGTEXT
,
VLC_FALSE
);
...
...
@@ -109,7 +109,6 @@ typedef struct bridged_es_t
block_t
*
p_block
;
block_t
**
pp_last
;
vlc_bool_t
b_empty
;
int
i_id
;
/* bridge in part */
sout_stream_id_t
*
id
;
...
...
@@ -150,9 +149,9 @@ static bridge_t *__GetBridge( vlc_object_t *p_object )
typedef
struct
out_sout_stream_sys_t
{
vlc_mutex_t
*
p_lock
;
bridged_es_t
*
p_es
;
int
i_id
;
vlc_bool_t
b_inited
;
int
i_position
;
}
out_sout_stream_sys_t
;
/*****************************************************************************
...
...
@@ -160,7 +159,7 @@ typedef struct out_sout_stream_sys_t
*****************************************************************************/
static
int
OpenOut
(
vlc_object_t
*
p_this
)
{
sout_stream_t
*
p_stream
=
(
sout_stream_t
*
)
p_this
;
sout_stream_t
*
p_stream
=
(
sout_stream_t
*
)
p_this
;
out_sout_stream_sys_t
*
p_sys
;
vlc_value_t
val
;
...
...
@@ -182,7 +181,6 @@ static int OpenOut( vlc_object_t *p_this )
p_stream
->
p_sys
=
(
sout_stream_sys_t
*
)
p_sys
;
/* update p_sout->i_out_pace_nocontrol */
p_stream
->
p_sout
->
i_out_pace_nocontrol
++
;
return
VLC_SUCCESS
;
...
...
@@ -243,14 +241,12 @@ static sout_stream_id_t * AddOut( sout_stream_t *p_stream, es_format_t *p_fmt )
p_bridge
->
pp_es
=
realloc
(
p_bridge
->
pp_es
,
(
p_bridge
->
i_es_num
+
1
)
*
sizeof
(
bridged_es_t
*
)
);
p_sys
->
i_position
=
p_bridge
->
i_es_num
;
p_bridge
->
i_es_num
++
;
p_bridge
->
pp_es
[
i
]
=
malloc
(
sizeof
(
bridged_es_t
)
);
}
else
p_sys
->
i_position
=
i
;
p_es
=
p_bridge
->
pp_es
[
p_sys
->
i_position
];
p_sys
->
p_es
=
p_es
=
p_bridge
->
pp_es
[
i
];
p_es
->
fmt
=
*
p_fmt
;
p_es
->
fmt
.
i_id
=
p_sys
->
i_id
;
p_es
->
p_block
=
NULL
;
...
...
@@ -262,7 +258,7 @@ static sout_stream_id_t * AddOut( sout_stream_t *p_stream, es_format_t *p_fmt )
p_es
->
b_changed
=
VLC_TRUE
;
msg_Dbg
(
p_stream
,
"bridging out input codec=%4.4s id=%d pos=%d"
,
(
char
*
)
&
p_es
->
fmt
.
i_codec
,
p_es
->
fmt
.
i_id
,
p_sys
->
i_position
);
(
char
*
)
&
p_es
->
fmt
.
i_codec
,
p_es
->
fmt
.
i_id
,
i
);
vlc_mutex_unlock
(
p_sys
->
p_lock
);
...
...
@@ -272,7 +268,6 @@ static sout_stream_id_t * AddOut( sout_stream_t *p_stream, es_format_t *p_fmt )
static
int
DelOut
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
)
{
out_sout_stream_sys_t
*
p_sys
=
(
out_sout_stream_sys_t
*
)
p_stream
->
p_sys
;
bridge_t
*
p_bridge
;
bridged_es_t
*
p_es
;
if
(
!
p_sys
->
b_inited
)
...
...
@@ -282,8 +277,7 @@ static int DelOut( sout_stream_t *p_stream, sout_stream_id_t *id )
vlc_mutex_lock
(
p_sys
->
p_lock
);
p_bridge
=
GetBridge
(
p_stream
);
p_es
=
p_bridge
->
pp_es
[
p_sys
->
i_position
];
p_es
=
p_sys
->
p_es
;
p_es
->
b_empty
=
VLC_TRUE
;
block_ChainRelease
(
p_es
->
p_block
);
...
...
@@ -299,7 +293,6 @@ static int SendOut( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t
*
p_buffer
)
{
out_sout_stream_sys_t
*
p_sys
=
(
out_sout_stream_sys_t
*
)
p_stream
->
p_sys
;
bridge_t
*
p_bridge
;
bridged_es_t
*
p_es
;
if
(
(
out_sout_stream_sys_t
*
)
id
!=
p_sys
)
...
...
@@ -310,8 +303,7 @@ static int SendOut( sout_stream_t *p_stream, sout_stream_id_t *id,
vlc_mutex_lock
(
p_sys
->
p_lock
);
p_bridge
=
GetBridge
(
p_stream
);
p_es
=
p_bridge
->
pp_es
[
p_sys
->
i_position
];
p_es
=
p_sys
->
p_es
;
*
p_es
->
pp_last
=
p_buffer
;
while
(
p_buffer
!=
NULL
)
{
...
...
modules/
video_output/pictur
e.c
→
modules/
stream_out/mosaic_bridg
e.c
View file @
f976d6ae
/*****************************************************************************
*
pictur
e.c:
*
mosaic_bridg
e.c:
*****************************************************************************
* Copyright (C) 2004-2005 VideoLAN
* $Id$
...
...
@@ -30,32 +30,33 @@
#include <string.h>
/* strerror() */
#include <vlc/vlc.h>
#include <vlc/vout.h>
#include <vlc/sout.h>
#include <vlc/decoder.h>
#include "vlc_image.h"
#include "
picture
.h"
#include "
../video_filter/mosaic
.h"
/*****************************************************************************
* Local structures
*****************************************************************************/
struct
vout
_sys_t
struct
sout_stream
_sys_t
{
picture_vout_t
*
p_picture_vout
;
bridged_es_t
*
p_es
;
vlc_mutex_t
*
p_lock
;
int
i_picture_pos
;
/* picture position in p_picture_vout */
image_handler_t
*
p_image
;
/* filters for resizing */
#ifdef IMAGE_2PASSES
image_handler_t
*
p_image2
;
#endif
decoder_t
*
p_decoder
;
image_handler_t
*
p_image
;
/* filter for resizing */
int
i_height
,
i_width
;
mtime_t
i_last_pic
;
char
*
psz_id
;
vlc_bool_t
b_inited
;
};
/* Delay after which the picture is blanked out if there hasn't been any
* new picture. */
#define BLANK_DELAY I64C(1000000)
#define PICTURE_RING_SIZE 64
struct
decoder_owner_sys_t
{
picture_t
*
pp_pics
[
PICTURE_RING_SIZE
];
};
typedef
void
(
*
pf_release_t
)(
picture_t
*
);
static
void
ReleasePicture
(
picture_t
*
p_pic
)
...
...
@@ -83,10 +84,14 @@ static void ReleasePicture( picture_t *p_pic )
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
int
Init
(
vout_thread_t
*
);
static
void
End
(
vout_thread_t
*
);
static
int
Manage
(
vout_thread_t
*
);
static
void
Display
(
vout_thread_t
*
,
picture_t
*
);
static
sout_stream_id_t
*
Add
(
sout_stream_t
*
,
es_format_t
*
);
static
int
Del
(
sout_stream_t
*
,
sout_stream_id_t
*
);
static
int
Send
(
sout_stream_t
*
,
sout_stream_id_t
*
,
block_t
*
);
static
void
video_del_buffer
(
decoder_t
*
,
picture_t
*
);
static
picture_t
*
video_new_buffer
(
decoder_t
*
);
static
void
video_link_picture_decoder
(
decoder_t
*
,
picture_t
*
);
static
void
video_unlink_picture_decoder
(
decoder_t
*
,
picture_t
*
);
/*****************************************************************************
* Module descriptor
...
...
@@ -102,226 +107,231 @@ static void Display ( vout_thread_t *, picture_t * );
#define HEIGHT_LONGTEXT N_( \
"Allows you to specify the output video height." )
vlc_module_begin
();
set_shortname
(
_
(
"Picture"
)
);
set_description
(
_
(
"VLC internal picture video output"
)
);
set_capability
(
"video output"
,
0
);
#define SOUT_CFG_PREFIX "sout-mosaic-bridge-"
add_string
(
"picture-id"
,
"Id"
,
NULL
,
ID_TEXT
,
ID_LONGTEXT
,
VLC_FALSE
);
add_integer
(
"picture-width"
,
0
,
NULL
,
WIDTH_TEXT
,
vlc_module_begin
();
set_shortname
(
_
(
"Mosaic bridge"
)
);
set_description
(
_
(
"Mosaic bridge stream output"
)
);
set_capability
(
"sout stream"
,
0
);
add_shortcut
(
"mosaic-bridge"
);
add_string
(
SOUT_CFG_PREFIX
"id"
,
"Id"
,
NULL
,
ID_TEXT
,
ID_LONGTEXT
,
VLC_FALSE
);
add_integer
(
SOUT_CFG_PREFIX
"width"
,
0
,
NULL
,
WIDTH_TEXT
,
WIDTH_LONGTEXT
,
VLC_TRUE
);
add_integer
(
"picture-
height"
,
0
,
NULL
,
HEIGHT_TEXT
,
add_integer
(
SOUT_CFG_PREFIX
"
height"
,
0
,
NULL
,
HEIGHT_TEXT
,
HEIGHT_LONGTEXT
,
VLC_TRUE
);
set_callbacks
(
Open
,
Close
);
var_Create
(
p_module
->
p_libvlc
,
"
picture
-lock"
,
VLC_VAR_MUTEX
);
var_Create
(
p_module
->
p_libvlc
,
"
mosaic
-lock"
,
VLC_VAR_MUTEX
);
vlc_module_end
();
static
const
char
*
ppsz_sout_options
[]
=
{
"id"
,
"width"
,
"height"
,
NULL
};
/*****************************************************************************
* Open
: allocate video thread output method
* Open
*****************************************************************************/
static
int
Open
(
vlc_object_t
*
p_this
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
vout_sys_t
*
p_sys
;
libvlc_t
*
p_libvlc
=
p_vout
->
p_libvlc
;
picture_vout_t
*
p_picture_vout
=
NULL
;
picture_vout_e_t
*
p_pic
;
vlc_value_t
val
,
lockval
;
p_sys
=
p_vout
->
p_sys
=
malloc
(
sizeof
(
vout_sys_t
)
);
if
(
p_sys
==
NULL
)
{
msg_Err
(
p_vout
,
"out of memory"
);
return
VLC_ENOMEM
;
}
sout_stream_t
*
p_stream
=
(
sout_stream_t
*
)
p_this
;
sout_stream_sys_t
*
p_sys
;
libvlc_t
*
p_libvlc
=
p_this
->
p_libvlc
;
vlc_value_t
val
;
var_Get
(
p_libvlc
,
"picture-lock"
,
&
lockval
);
p_sys
->
p_lock
=
lockval
.
p_address
;
vlc_mutex_lock
(
p_sys
->
p_lock
);
sout_CfgParse
(
p_stream
,
SOUT_CFG_PREFIX
,
ppsz_sout_options
,
p_stream
->
p_cfg
);
p_sys
->
i_picture_pos
=
-
1
;
if
(
var_Get
(
p_libvlc
,
"p_picture_vout"
,
&
val
)
!=
VLC_SUCCESS
)
{
p_picture_vout
=
malloc
(
sizeof
(
struct
picture_vout_t
)
);
if
(
p_picture_vout
==
NULL
)
{
msg_Err
(
p_vout
,
"out of memory"
);
return
VLC_ENOMEM
;
}
p_sys
=
malloc
(
sizeof
(
sout_stream_sys_t
)
);
p_stream
->
p_sys
=
p_sys
;
p_sys
->
b_inited
=
VLC_FALSE
;
var_Create
(
p_libvlc
,
"p_picture_vout"
,
VLC_VAR_ADDRESS
);
val
.
p_address
=
p_picture_vout
;
var_Set
(
p_libvlc
,
"p_picture_vout"
,
val
);
var_Get
(
p_libvlc
,
"mosaic-lock"
,
&
val
);
p_sys
->
p_lock
=
val
.
p_address
;
p_picture_vout
->
i_picture_num
=
0
;
p_picture_vout
->
p_pic
=
NULL
;
}
else
{
int
i
;
p_picture_vout
=
val
.
p_address
;
for
(
i
=
0
;
i
<
p_picture_vout
->
i_picture_num
;
i
++
)
{
if
(
p_picture_vout
->
p_pic
[
i
].
i_status
==
PICTURE_VOUT_E_AVAILABLE
)
break
;
}
if
(
i
!=
p_picture_vout
->
i_picture_num
)
p_sys
->
i_picture_pos
=
i
;
}
p_sys
->
p_picture_vout
=
p_picture_vout
;
if
(
p_sys
->
i_picture_pos
==
-
1
)
{
p_picture_vout
->
p_pic
=
realloc
(
p_picture_vout
->
p_pic
,
(
p_picture_vout
->
i_picture_num
+
1
)
*
sizeof
(
picture_vout_e_t
)
);
p_sys
->
i_picture_pos
=
p_picture_vout
->
i_picture_num
;
p_picture_vout
->
i_picture_num
++
;
}
p_pic
=
&
p_picture_vout
->
p_pic
[
p_sys
->
i_picture_pos
];
p_pic
->
p_picture
=
NULL
;
p_pic
->
i_status
=
PICTURE_VOUT_E_OCCUPIED
;
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"id"
,
&
val
);
p_sys
->
psz_id
=
val
.
psz_string
;
var_Create
(
p_vout
,
"picture-id"
,
VLC_VAR_STRING
);
var_Change
(
p_vout
,
"picture-id"
,
VLC_VAR_INHERITVALUE
,
&
val
,
NULL
);
p_pic
->
psz_id
=
val
.
psz_string
;
vlc_mutex_unlock
(
p_sys
->
p_lock
);
var_Create
(
p_vout
,
"picture-height"
,
VLC_VAR_INTEGER
);
var_Change
(
p_vout
,
"picture-height"
,
VLC_VAR_INHERITVALUE
,
&
val
,
NULL
);
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"height"
,
&
val
);
p_sys
->
i_height
=
val
.
i_int
;
var_Create
(
p_vout
,
"picture-width"
,
VLC_VAR_INTEGER
);
var_Change
(
p_vout
,
"picture-width"
,
VLC_VAR_INHERITVALUE
,
&
val
,
NULL
);
var_Get
(
p_stream
,
SOUT_CFG_PREFIX
"width"
,
&
val
);
p_sys
->
i_width
=
val
.
i_int
;
if
(
p_sys
->
i_height
||
p_sys
->
i_width
)
{
p_sys
->
p_image
=
image_HandlerCreate
(
p_vout
);
#ifdef IMAGE_2PASSES
p_sys
->
p_image2
=
image_HandlerCreate
(
p_vout
);
#endif
p_sys
->
p_image
=
image_HandlerCreate
(
p_stream
);
}
p_sys
->
i_last_pic
=
0
;
p_stream
->
pf_add
=
Add
;
p_stream
->
pf_del
=
Del
;
p_stream
->
pf_send
=
Send
;
p_vout
->
pf_init
=
Init
;
p_vout
->
pf_end
=
End
;
p_vout
->
pf_manage
=
Manage
;
p_vout
->
pf_render
=
NULL
;
p_vout
->
pf_display
=
Display
;
p_stream
->
p_sout
->
i_out_pace_nocontrol
++
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
*
Init
*
Close
*****************************************************************************/
static
int
Init
(
vout_thread_t
*
p_vout
)
static
void
Close
(
vlc_object_t
*
p_this
)
{
picture_t
*
p_pic
;
int
i_index
;
sout_stream_t
*
p_stream
=
(
sout_stream_t
*
)
p_this
;
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
p_stream
->
p_sout
->
i_out_pace_nocontrol
--
;
I_OUTPUTPICTURES
=
0
;
if
(
p_sys
->
psz_id
)
free
(
p_sys
->
psz_id
);
p_vout
->
output
.
i_chroma
=
p_vout
->
render
.
i_chroma
;
p_vout
->
output
.
i_width
=
p_vout
->
render
.
i_width
;
p_vout
->
output
.
i_height
=
p_vout
->
render
.
i_height
;
p_vout
->
output
.
i_aspect
=
p_vout
->
render
.
i_aspect
;
free
(
p_sys
);
}
static
sout_stream_id_t
*
Add
(
sout_stream_t
*
p_stream
,
es_format_t
*
p_fmt
)
{
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
bridge_t
*
p_bridge
;
bridged_es_t
*
p_es
;
int
i
;
while
(
VLC_TRUE
)
if
(
p_sys
->
b_inited
)
{
p_pic
=
NULL
;
return
NULL
;
}
for
(
i_index
=
0
;
i_index
<
VOUT_MAX_PICTURES
;
i_index
++
)
{
if
(
p_vout
->
p_picture
[
i_index
].
i_status
==
FREE_PICTURE
)
{
p_pic
=
p_vout
->
p_picture
+
i_index
;
break
;
}
}
/* Create decoder object */
p_sys
->
p_decoder
=
vlc_object_create
(
p_stream
,
VLC_OBJECT_DECODER
);
vlc_object_attach
(
p_sys
->
p_decoder
,
p_stream
);
p_sys
->
p_decoder
->
p_module
=
NULL
;
p_sys
->
p_decoder
->
fmt_in
=
*
p_fmt
;
p_sys
->
p_decoder
->
b_pace_control
=
VLC_FALSE
;
p_sys
->
p_decoder
->
fmt_out
=
p_sys
->
p_decoder
->
fmt_in
;
p_sys
->
p_decoder
->
fmt_out
.
i_extra
=
0
;
p_sys
->
p_decoder
->
fmt_out
.
p_extra
=
0
;
p_sys
->
p_decoder
->
pf_decode_video
=
0
;
p_sys
->
p_decoder
->
pf_vout_buffer_new
=
video_new_buffer
;
p_sys
->
p_decoder
->
pf_vout_buffer_del
=
video_del_buffer
;
p_sys
->
p_decoder
->
pf_picture_link
=
video_link_picture_decoder
;
p_sys
->
p_decoder
->
pf_picture_unlink
=
video_unlink_picture_decoder
;
p_sys
->
p_decoder
->
p_owner
=
malloc
(
sizeof
(
decoder_owner_sys_t
)
);
for
(
i
=
0
;
i
<
PICTURE_RING_SIZE
;
i
++
)
p_sys
->
p_decoder
->
p_owner
->
pp_pics
[
i
]
=
0
;
//p_sys->p_decoder->p_cfg = p_sys->p_video_cfg;
p_sys
->
p_decoder
->
p_module
=
module_Need
(
p_sys
->
p_decoder
,
"decoder"
,
"$codec"
,
0
);
if
(
!
p_sys
->
p_decoder
->
p_module
)
{
msg_Err
(
p_stream
,
"cannot find decoder"
);
vlc_object_detach
(
p_sys
->
p_decoder
);
vlc_object_destroy
(
p_sys
->
p_decoder
);
return
NULL
;
}
if
(
p_pic
==
NULL
)
{
return
VLC_SUCCESS
;
}
p_sys
->
b_inited
=
VLC_TRUE
;
vlc_mutex_lock
(
p_sys
->
p_lock
);
vout_AllocatePicture
(
VLC_OBJECT
(
p_vout
),
p_pic
,
p_vout
->
output
.
i_chroma
,
p_vout
->
output
.
i_width
,
p_vout
->
output
.
i_height
,
p_vout
->
output
.
i_aspect
);
p_bridge
=
GetBridge
(
p_stream
);
if
(
p_bridge
==
NULL
)
{
libvlc_t
*
p_libvlc
=
p_stream
->
p_libvlc
;
vlc_value_t
val
;
if
(
p_pic
->
i_planes
==
0
)
{
return
VLC_EGENERIC
;
}
p_bridge
=
malloc
(
sizeof
(
bridge_t
)
);
p_pic
->
i_status
=
DESTROYED_PICTURE
;
p_pic
->
i_type
=
DIRECT_PICTURE
;
var_Create
(
p_libvlc
,
"mosaic-struct"
,
VLC_VAR_ADDRESS
);
val
.
p_address
=
p_bridge
;
var_Set
(
p_libvlc
,
"mosaic-struct"
,
val
);
PP_OUTPUTPICTURE
[
I_OUTPUTPICTURES
]
=
p_pic
;
p_bridge
->
i_es_num
=
0
;
p_bridge
->
pp_es
=
NULL
;
}
I_OUTPUTPICTURES
++
;
for
(
i
=
0
;
i
<
p_bridge
->
i_es_num
;
i
++
)
{
if
(
p_bridge
->
pp_es
[
i
]
->
b_empty
)
break
;
}
//return VLC_SUCCESS;
if
(
i
==
p_bridge
->
i_es_num
)
{
p_bridge
->
pp_es
=
realloc
(
p_bridge
->
pp_es
,
(
p_bridge
->
i_es_num
+
1
)
*
sizeof
(
bridged_es_t
*
)
);
p_bridge
->
i_es_num
++
;
p_bridge
->
pp_es
[
i
]
=
malloc
(
sizeof
(
bridged_es_t
)
);
}
}
p_sys
->
p_es
=
p_es
=
p_bridge
->
pp_es
[
i
];
/*****************************************************************************
* End
*****************************************************************************/
static
void
End
(
vout_thread_t
*
p_vout
)
{
return
;
//p_es->fmt = *p_fmt;
p_es
->
psz_id
=
p_sys
->
psz_id
;
p_es
->
p_picture
=
NULL
;
p_es
->
pp_last
=
&
p_es
->
p_picture
;
p_es
->
b_empty
=
VLC_FALSE
;
vlc_mutex_unlock
(
p_sys
->
p_lock
);
msg_Dbg
(
p_stream
,
"mosaic bridge id=%s pos=%d"
,
p_es
->
psz_id
,
i
);
return
(
sout_stream_id_t
*
)
p_sys
;
}
/*****************************************************************************
* Close
*****************************************************************************/
static
void
Close
(
vlc_object_t
*
p_this
)
static
int
Del
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
picture_vout_t
*
p_picture_vout
=
p_sys
->
p_picture_vout
;
picture_vout_e_t
*
p_pic
;
vlc_bool_t
b_last_picture
=
VLC_TRUE
;
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
bridge_t
*
p_bridge
;
bridged_es_t
*
p_es
;
vlc_bool_t
b_last_es
=
VLC_TRUE
;
int
i
;
if
(
!
p_sys
->
b_inited
)
{
return
VLC_SUCCESS
;
}
if
(
p_sys
->
p_decoder
)
{
if
(
p_sys
->
p_decoder
->
p_module
)
module_Unneed
(
p_sys
->
p_decoder
,
p_sys
->
p_decoder
->
p_module
);
vlc_object_detach
(
p_sys
->
p_decoder
);
vlc_object_destroy
(
p_sys
->
p_decoder
);
}
vlc_mutex_lock
(
p_sys
->
p_lock
);
p_pic
=
&
p_picture_vout
->
p_pic
[
p_sys
->
i_picture_pos
];
if
(
p_pic
->
p_picture
)
p_bridge
=
GetBridge
(
p_stream
);
p_es
=
p_sys
->
p_es
;
p_es
->
b_empty
=
VLC_TRUE
;
while
(
p_es
->
p_picture
)
{
p_pic
->
p_picture
->
pf_release
(
p_pic
->
p_picture
);
p_pic
->
p_picture
=
NULL
;
picture_t
*
p_next
=
p_es
->
p_picture
->
p_next
;
p_es
->
p_picture
->
pf_release
(
p_es
->
p_picture
);
p_es
->
p_picture
=
p_next
;
}
p_pic
->
i_status
=
PICTURE_VOUT_E_AVAILABLE
;
if
(
p_pic
->
psz_id
)
free
(
p_pic
->
psz_id
);
for
(
i
=
0
;
i
<
p_picture_vout
->
i_picture_num
;
i
++
)
for
(
i
=
0
;
i
<
p_bridge
->
i_es_num
;
i
++
)
{
if
(
p_picture_vout
->
p_pic
[
i
].
i_status
==
PICTURE_VOUT_E_OCCUPIED
)
if
(
!
p_bridge
->
pp_es
[
i
]
->
b_empty
)
{
b_last_
picture
=
VLC_FALSE
;
b_last_
es
=
VLC_FALSE
;
break
;
}
}
if
(
b_last_picture
)
if
(
b_last_es
)
{
free
(
p_picture_vout
->
p_pic
);
free
(
p_picture_vout
);
var_Destroy
(
p_this
->
p_libvlc
,
"p_picture_vout"
);
libvlc_t
*
p_libvlc
=
p_stream
->
p_libvlc
;
for
(
i
=
0
;
i
<
p_bridge
->
i_es_num
;
i
++
)
free
(
p_bridge
->
pp_es
[
i
]
);
free
(
p_bridge
->
pp_es
);
free
(
p_bridge
);
var_Destroy
(
p_libvlc
,
"mosaic-struct"
);
}
vlc_mutex_unlock
(
p_sys
->
p_lock
);
...
...
@@ -329,160 +339,174 @@ static void Close( vlc_object_t *p_this )
if
(
p_sys
->
i_height
||
p_sys
->
i_width
)
{
image_HandlerDelete
(
p_sys
->
p_image
);
#ifdef IMAGE_2PASSES
image_HandlerDelete
(
p_sys
->
p_image2
);
#endif
}
free
(
p_sys
);
p_sys
->
b_inited
=
VLC_FALSE
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* PushPicture : push a picture in the
p_picture_vou
t structure
* PushPicture : push a picture in the
mosaic-struc
t structure
*****************************************************************************/
static
void
PushPicture
(
vout_thread_t
*
p_vout
,
picture_t
*
p_picture
)
static
void
PushPicture
(
sout_stream_t
*
p_stream
,
picture_t
*
p_picture
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
picture_vout_t
*
p_picture_vout
=
p_sys
->
p_picture_vout
;
picture_vout_e_t
*
p_pic
;
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
bridged_es_t
*
p_es
=
p_sys
->
p_es
;
vlc_mutex_lock
(
p_sys
->
p_lock
);
p_pic
=
&
p_picture_vout
->
p_pic
[
p_sys
->
i_picture_pos
];
if
(
p_pic
->
p_picture
!=
NULL
)
{
p_pic
->
p_picture
->
pf_release
(
p_pic
->
p_picture
);
}
p_pic
->
p_picture
=
p_picture
;
*
p_es
->
pp_last
=
p_picture
;
p_picture
->
p_next
=
NULL
;
p_es
->
pp_last
=
&
p_picture
->
p_next
;
vlc_mutex_unlock
(
p_sys
->
p_lock
);
}
/*****************************************************************************
* Manage
*****************************************************************************/
static
int
Manage
(
vout_thread_t
*
p_vout
)
static
int
Send
(
sout_stream_t
*
p_stream
,
sout_stream_id_t
*
id
,
block_t
*
p_buffer
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
sout_stream_sys_t
*
p_sys
=
p_stream
->
p_sys
;
picture_t
*
p_pic
;
if
(
(
sout_stream_sys_t
*
)
id
!=
p_sys
)
{
block_ChainRelease
(
p_buffer
);
return
VLC_SUCCESS
;
}
if
(
mdate
()
-
p_sys
->
i_last_pic
>
BLANK_DELAY
)
while
(
(
p_pic
=
p_sys
->
p_decoder
->
pf_decode_video
(
p_sys
->
p_decoder
,
&
p_buffer
))
)
{
/* Display black */
#if 0
picture_t *p_new_pic = (picture_t*)malloc( sizeof(picture_t) );
int i;
picture_t
*
p_new_pic
;
if
(
p_sys
->
i_height
||
p_sys
->
i_width
)
{
vout_AllocatePicture( p_vout, p_new_pic,
VLC_FOURCC('Y','U','V','A'),
p_sys->i_width, p_sys->i_height,
p_vout->render.i_aspect );
video_format_t
fmt_out
=
{
0
},
fmt_in
=
{
0
};
fmt_in
=
p_sys
->
p_decoder
->
fmt_out
.
video
;
fmt_out
.
i_chroma
=
VLC_FOURCC
(
'Y'
,
'U'
,
'V'
,
'A'
);
fmt_out
.
i_width
=
p_sys
->
i_width
;
fmt_out
.
i_height
=
p_sys
->
i_height
;
fmt_out
.
i_visible_width
=
fmt_out
.
i_width
;
fmt_out
.
i_visible_height
=
fmt_out
.
i_height
;
p_new_pic
=
image_Convert
(
p_sys
->
p_image
,
p_pic
,
&
fmt_in
,
&
fmt_out
);
if
(
p_new_pic
==
NULL
)
{
msg_Err
(
p_stream
,
"image conversion failed"
);
continue
;
}
}
else
{
vout_AllocatePicture( p_vout, p_new_pic, p_vout->render.i_chroma,
p_vout->render.i_width,
p_vout->render.i_height,
p_vout->render.i_aspect );
p_new_pic
=
(
picture_t
*
)
malloc
(
sizeof
(
picture_t
)
);
vout_AllocatePicture
(
p_stream
,
p_new_pic
,
p_pic
->
format
.
i_chroma
,
p_pic
->
format
.
i_width
,
p_pic
->
format
.
i_height
,
p_sys
->
p_decoder
->
fmt_out
.
video
.
i_aspect
);
vout_CopyPicture
(
p_stream
,
p_new_pic
,
p_pic
);
}
p_pic
->
pf_release
(
p_pic
);
p_new_pic->i_refcount
++
;
p_new_pic
->
i_refcount
=
1
;
p_new_pic
->
i_status
=
DESTROYED_PICTURE
;
p_new_pic
->
i_type
=
DIRECT_PICTURE
;
p_new_pic
->
p_sys
=
(
picture_sys_t
*
)
p_new_pic
->
pf_release
;
p_new_pic
->
pf_release
=
ReleasePicture
;
p_new_pic
->
date
=
p_pic
->
date
;
for ( i = 0; i < p_pic->i_planes; i++ )
{
/* This assumes planar YUV format */
p_vout->p_vlc->pf_memset( p_pic->p[i].p_pixels, i ? 0x80 : 0,
p_pic->p[i].i_lines
* p_pic->p[i].i_pitch );
}
PushPicture( p_vout, p_new_pic );
#else
PushPicture
(
p_vout
,
NULL
);
#endif
p_sys
->
i_last_pic
=
INT64_MAX
;
PushPicture
(
p_stream
,
p_new_pic
);
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Display
*****************************************************************************/
static
void
Display
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
struct
picture_sys_t
{
v
out_sys_t
*
p_sys
=
p_vout
->
p_sys
;
picture_t
*
p_new_pic
;
v
lc_object_t
*
p_owner
;
}
;
if
(
p_sys
->
i_height
||
p_sys
->
i_width
)
static
void
video_release_buffer
(
picture_t
*
p_pic
)
{
if
(
p_pic
&&
!
p_pic
->
i_refcount
&&
p_pic
->
pf_release
&&
p_pic
->
p_sys
)
{
video_format_t
fmt_out
=
{
0
},
fmt_in
=
{
0
};
#ifdef IMAGE_2PASSES
vide_format_t
fmt_middle
=
{
0
};
picture_t
*
p_new_pic2
;
#endif
fmt_in
=
p_vout
->
fmt_in
;
#ifdef IMAGE_2PASSES
fmt_middle
.
i_chroma
=
p_vout
->
render
.
i_chroma
;
fmt_middle
.
i_width
=
p_vout
->
p_sys
->
i_width
;
fmt_middle
.
i_height
=
p_vout
->
p_sys
->
i_height
;
fmt_middle
.
i_visible_width
=
fmt_middle
.
i_width
;
fmt_middle
.
i_visible_height
=
fmt_middle
.
i_height
;
p_new_pic2
=
image_Convert
(
p_vout
->
p_sys
->
p_image2
,
p_pic
,
&
fmt_in
,
&
fmt_middle
);
if
(
p_new_pic2
==
NULL
)
video_del_buffer
(
(
decoder_t
*
)
p_pic
->
p_sys
->
p_owner
,
p_pic
);
}
else
if
(
p_pic
&&
p_pic
->
i_refcount
>
0
)
p_pic
->
i_refcount
--
;
}
static
picture_t
*
video_new_buffer
(
decoder_t
*
p_dec
)
{
picture_t
**
pp_ring
=
p_dec
->
p_owner
->
pp_pics
;
picture_t
*
p_pic
;
int
i
;
/* Find an empty space in the picture ring buffer */
for
(
i
=
0
;
i
<
PICTURE_RING_SIZE
;
i
++
)
{
if
(
pp_ring
[
i
]
!=
0
&&
pp_ring
[
i
]
->
i_status
==
DESTROYED_PICTURE
)
{
msg_Err
(
p_vout
,
"image resizing failed %dx%d->%dx%d %4.4s"
,
p_vout
->
render
.
i_width
,
p_vout
->
render
.
i_height
,
fmt_middle
.
i_width
,
fmt_middle
.
i_height
,
(
char
*
)
&
p_vout
->
render
.
i_chroma
);
return
;
pp_ring
[
i
]
->
i_status
=
RESERVED_PICTURE
;
return
pp_ring
[
i
];
}
#endif
fmt_out
.
i_chroma
=
VLC_FOURCC
(
'Y'
,
'U'
,
'V'
,
'A'
);
fmt_out
.
i_width
=
p_sys
->
i_width
;
fmt_out
.
i_height
=
p_sys
->
i_height
;
fmt_out
.
i_visible_width
=
fmt_out
.
i_width
;
fmt_out
.
i_visible_height
=
fmt_out
.
i_height
;
#ifdef IMAGE_2PASSES
p_new_pic
=
image_Convert
(
p_vout
->
p_sys
->
p_image
,
p_new_pic2
,
&
fmt_middle
,
&
fmt_out
);
p_new_pic2
->
pf_release
(
p_new_pic2
);
#else
p_new_pic
=
image_Convert
(
p_vout
->
p_sys
->
p_image
,
p_pic
,
&
fmt_in
,
&
fmt_out
);
#endif
if
(
p_new_pic
==
NULL
)
}
for
(
i
=
0
;
i
<
PICTURE_RING_SIZE
;
i
++
)
{
if
(
pp_ring
[
i
]
==
0
)
break
;
}
if
(
i
==
PICTURE_RING_SIZE
)
{
msg_Err
(
p_dec
,
"decoder/filter is leaking pictures, "
"resetting its ring buffer"
);
for
(
i
=
0
;
i
<
PICTURE_RING_SIZE
;
i
++
)
{
msg_Err
(
p_vout
,
"image conversion failed"
);
return
;
pp_ring
[
i
]
->
pf_release
(
pp_ring
[
i
]
);
}
i
=
0
;
}
else
{
p_new_pic
=
(
picture_t
*
)
malloc
(
sizeof
(
picture_t
)
);
vout_AllocatePicture
(
p_vout
,
p_new_pic
,
p_pic
->
format
.
i_chroma
,
p_pic
->
format
.
i_width
,
p_pic
->
format
.
i_height
,
p_vout
->
render
.
i_aspect
);
vout_CopyPicture
(
p_vout
,
p_new_pic
,
p_pic
);
p_pic
=
malloc
(
sizeof
(
picture_t
)
);
p_dec
->
fmt_out
.
video
.
i_chroma
=
p_dec
->
fmt_out
.
i_codec
;
vout_AllocatePicture
(
VLC_OBJECT
(
p_dec
),
p_pic
,
p_dec
->
fmt_out
.
video
.
i_chroma
,
p_dec
->
fmt_out
.
video
.
i_width
,
p_dec
->
fmt_out
.
video
.
i_height
,
p_dec
->
fmt_out
.
video
.
i_aspect
);
if
(
!
p_pic
->
i_planes
)
{
free
(
p_pic
);
return
0
;
}
p_new_pic
->
i_refcount
=
1
;
p_new_pic
->
i_status
=
DESTROYED_PICTURE
;
p_new_pic
->
i_type
=
DIRECT_PICTURE
;
p_new_pic
->
p_sys
=
(
picture_sys_t
*
)
p_new_pic
->
pf_release
;
p_new_pic
->
pf_release
=
ReleasePicture
;
p_pic
->
pf_release
=
video_release_buffer
;
p_pic
->
p_sys
=
malloc
(
sizeof
(
picture_sys_t
)
);
p_pic
->
p_sys
->
p_owner
=
VLC_OBJECT
(
p_dec
);
p_pic
->
i_status
=
RESERVED_PICTURE
;
PushPicture
(
p_vout
,
p_new_pic
);
p_sys
->
i_last_pic
=
p_pic
->
date
;
pp_ring
[
i
]
=
p_pic
;
return
p_pic
;
}
static
void
video_del_buffer
(
decoder_t
*
p_this
,
picture_t
*
p_pic
)
{
p_pic
->
i_refcount
=
0
;
p_pic
->
i_status
=
DESTROYED_PICTURE
;
}
static
void
video_link_picture_decoder
(
decoder_t
*
p_dec
,
picture_t
*
p_pic
)
{
p_pic
->
i_refcount
++
;
}
static
void
video_unlink_picture_decoder
(
decoder_t
*
p_dec
,
picture_t
*
p_pic
)
{
video_release_buffer
(
p_pic
);
}
modules/video_filter/Modules.am
View file @
f976d6ae
SOURCES_mosaic = mosaic.c
SOURCES_mosaic = mosaic.c
mosaic.h
SOURCES_transform = transform.c
SOURCES_invert = invert.c
SOURCES_adjust = adjust.c
...
...
modules/video_filter/mosaic.c
View file @
f976d6ae
...
...
@@ -39,7 +39,9 @@
#include "vlc_filter.h"
#include "vlc_image.h"
#include "../video_output/picture.h"
#include "mosaic.h"
#define BLANK_DELAY I64C(1000000)
/*****************************************************************************
* Local prototypes
...
...
@@ -58,11 +60,9 @@ static int MosaicCallback( vlc_object_t *, char const *, vlc_value_t,
struct
filter_sys_t
{
vlc_mutex_t
lock
;
vlc_mutex_t
*
p_lock
;
image_handler_t
*
p_image
;
#ifdef IMAGE_2PASSES
image_handler_t
*
p_image2
;
#endif
picture_t
*
p_pic
;
int
i_position
;
/* mosaic positioning method */
...
...
@@ -108,7 +108,7 @@ struct filter_sys_t
#define DELAY_TEXT N_("Delay")
#define DELAY_LONGTEXT N_("Pictures coming from the picture video outputs " \
"will be delayed accordingly (in milliseconds
, >= 100 ms
). For high " \
"will be delayed accordingly (in milliseconds). For high " \
"values you will need to raise file-caching and others.")
static
int
pi_pos_values
[]
=
{
0
,
1
};
...
...
@@ -145,8 +145,10 @@ vlc_module_begin();
add_bool
(
"mosaic-keep-picture"
,
0
,
NULL
,
KEEP_TEXT
,
KEEP_TEXT
,
VLC_FALSE
);
add_string
(
"mosaic-order"
,
""
,
NULL
,
ORDER_TEXT
,
ORDER_TEXT
,
VLC_FALSE
);
add_integer
(
"mosaic-delay"
,
10
0
,
NULL
,
DELAY_TEXT
,
DELAY_LONGTEXT
,
add_integer
(
"mosaic-delay"
,
0
,
NULL
,
DELAY_TEXT
,
DELAY_LONGTEXT
,
VLC_FALSE
);
var_Create
(
p_module
->
p_libvlc
,
"mosaic-lock"
,
VLC_VAR_MUTEX
);
vlc_module_end
();
...
...
@@ -160,6 +162,7 @@ static int CreateFilter( vlc_object_t *p_this )
libvlc_t
*
p_libvlc
=
p_filter
->
p_libvlc
;
char
*
psz_order
;
int
i_index
;
vlc_value_t
val
;
/* Allocate structure */
p_sys
=
p_filter
->
p_sys
=
malloc
(
sizeof
(
filter_sys_t
)
);
...
...
@@ -175,6 +178,9 @@ static int CreateFilter( vlc_object_t *p_this )
vlc_mutex_init
(
p_filter
,
&
p_sys
->
lock
);
vlc_mutex_lock
(
&
p_sys
->
lock
);
var_Get
(
p_libvlc
,
"mosaic-lock"
,
&
val
);
p_sys
->
p_lock
=
val
.
p_address
;
#define GET_VAR( name, min, max ) \
p_sys->i_##name = __MIN( max, __MAX( min, \
var_CreateGetInteger( p_filter, "mosaic-" #name ) ) ); \
...
...
@@ -216,9 +222,6 @@ static int CreateFilter( vlc_object_t *p_this )
if
(
!
p_sys
->
b_keep
)
{
p_sys
->
p_image
=
image_HandlerCreate
(
p_filter
);
#ifdef IMAGE_2PASSES
p_sys
->
p_image2
=
image_HandlerCreate
(
p_filter
);
#endif
}
p_sys
->
i_order_length
=
0
;
...
...
@@ -244,8 +247,6 @@ static int CreateFilter( vlc_object_t *p_this )
vlc_mutex_unlock
(
&
p_sys
->
lock
);
vlc_thread_set_priority
(
p_filter
,
VLC_THREAD_PRIORITY_OUTPUT
);
return
VLC_SUCCESS
;
}
...
...
@@ -264,9 +265,6 @@ static void DestroyFilter( vlc_object_t *p_this )
if
(
!
p_sys
->
b_keep
)
{
image_HandlerDelete
(
p_sys
->
p_image
);
#ifdef IMAGE_2PASSES
image_HandlerDelete
(
p_sys
->
p_image2
);
#endif
}
if
(
p_sys
->
i_order_length
)
...
...
@@ -313,7 +311,7 @@ static void MosaicReleasePicture( picture_t *p_picture )
static
subpicture_t
*
Filter
(
filter_t
*
p_filter
,
mtime_t
date
)
{
filter_sys_t
*
p_sys
=
p_filter
->
p_sys
;
libvlc_t
*
p_libvlc
=
p_filter
->
p_libvlc
;
bridge_t
*
p_bridge
;
subpicture_t
*
p_spu
;
...
...
@@ -323,26 +321,6 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
subpicture_region_t
*
p_region
;
subpicture_region_t
*
p_region_prev
=
NULL
;
picture_vout_t
*
p_picture_vout
;
vlc_value_t
val
,
lockval
;
/* Wait for the specified date. This is to avoid running too fast and
* take twice the same pictures. */
mwait
(
date
-
p_sys
->
i_delay
);
if
(
var_Get
(
p_libvlc
,
"picture-lock"
,
&
lockval
)
)
return
NULL
;
vlc_mutex_lock
(
lockval
.
p_address
);
if
(
var_Get
(
p_libvlc
,
"p_picture_vout"
,
&
val
)
)
{
vlc_mutex_unlock
(
lockval
.
p_address
);
return
NULL
;
}
p_picture_vout
=
val
.
p_address
;
/* Allocate the subpicture internal data. */
p_spu
=
p_filter
->
pf_sub_buffer_new
(
p_filter
);
if
(
!
p_spu
)
...
...
@@ -360,28 +338,33 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
p_spu
->
b_absolute
=
VLC_FALSE
;
vlc_mutex_lock
(
&
p_sys
->
lock
);
vlc_mutex_lock
(
p_sys
->
p_lock
);
p_bridge
=
GetBridge
(
p_filter
);
if
(
p_bridge
==
NULL
)
{
vlc_mutex_unlock
(
p_sys
->
p_lock
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
return
p_spu
;
}
if
(
p_sys
->
i_position
==
0
)
/* use automatic positioning */
if
(
p_sys
->
i_position
==
0
)
/* use automatic positioning */
{
int
i_numpics
=
p_sys
->
i_order_length
;
/* keep slots and all */
for
(
i_index
=
0
;
i_index
<
p_picture_vout
->
i_picture_num
;
i_index
++
)
for
(
i_index
=
0
;
i_index
<
p_bridge
->
i_es_num
;
i_index
++
)
{
if
(
p_picture_vout
->
p_pic
[
i_index
].
i_status
==
PICTURE_VOUT_E_OCCUPIED
)
bridged_es_t
*
p_es
=
p_bridge
->
pp_es
[
i_index
];
if
(
!
p_es
->
b_empty
)
{
i_numpics
++
;
if
(
p_sys
->
i_order_length
&&
p_picture_vout
->
p_pic
[
i_index
].
psz_id
!=
0
)
if
(
p_sys
->
i_order_length
&&
p_es
->
psz_id
!=
0
)
{
/* We also want to leave slots for images given in
* mosaic-order that are not available in p_vout_picture */
int
i
;
for
(
i
=
0
;
i
<
p_sys
->
i_order_length
;
i
++
)
{
if
(
!
strcmp
(
p_sys
->
ppsz_order
[
i
],
p_picture_vout
->
p_pic
[
i_index
].
psz_id
)
)
if
(
!
strcmp
(
p_sys
->
ppsz_order
[
i
],
p_es
->
psz_id
)
)
{
i_numpics
--
;
break
;
...
...
@@ -399,50 +382,66 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
i_real_index
=
0
;
for
(
i_index
=
0
;
i_index
<
p_picture_vout
->
i_picture
_num
;
i_index
++
)
for
(
i_index
=
0
;
i_index
<
p_bridge
->
i_es
_num
;
i_index
++
)
{
picture_vout_e_t
*
p_pic
=
&
p_picture_vout
->
p_pic
[
i_index
];
bridged_es_t
*
p_es
=
p_bridge
->
pp_es
[
i_index
];
video_format_t
fmt_in
=
{
0
},
fmt_out
=
{
0
};
picture_t
*
p_converted
;
#ifdef IMAGE_2PASSES
video_format_t
fmt_middle
=
{
0
};
picture_t
*
p_middle
;
#endif
if
(
p_pic
->
i_status
==
PICTURE_VOUT_E_AVAILABLE
||
p_pic
->
p_picture
==
NULL
)
{
if
(
p_es
->
b_empty
||
p_es
->
p_picture
==
NULL
)
continue
;
if
(
p_es
->
p_picture
->
date
+
p_sys
->
i_delay
<
date
)
{
if
(
p_es
->
p_picture
->
p_next
!=
NULL
)
{
picture_t
*
p_next
=
p_es
->
p_picture
->
p_next
;
p_es
->
p_picture
->
pf_release
(
p_es
->
p_picture
);
p_es
->
p_picture
=
p_next
;
}
else
if
(
p_es
->
p_picture
->
date
+
p_sys
->
i_delay
+
BLANK_DELAY
<
date
)
{
/* Display blank */
p_es
->
p_picture
->
pf_release
(
p_es
->
p_picture
);
p_es
->
p_picture
=
NULL
;
p_es
->
pp_last
=
&
p_es
->
p_picture
;
continue
;
}
else
msg_Dbg
(
p_filter
,
"too late picture %lld for %s"
,
date
-
p_es
->
p_picture
->
date
-
p_sys
->
i_delay
,
p_es
->
psz_id
);
}
if
(
p_sys
->
i_order_length
==
0
)
if
(
p_sys
->
i_order_length
==
0
)
{
i_real_index
++
;
}
else
{
int
i
;
for
(
i
=
0
;
i
<=
p_sys
->
i_order_length
;
i
++
)
for
(
i
=
0
;
i
<=
p_sys
->
i_order_length
;
i
++
)
{
if
(
i
==
p_sys
->
i_order_length
)
break
;
if
(
strcmp
(
p_pic
->
psz_id
,
p_sys
->
ppsz_order
[
i
]
)
==
0
)
if
(
i
==
p_sys
->
i_order_length
)
break
;
if
(
strcmp
(
p_es
->
psz_id
,
p_sys
->
ppsz_order
[
i
]
)
==
0
)
{
i_real_index
=
i
;
break
;
}
}
if
(
i
==
p_sys
->
i_order_length
)
if
(
i
==
p_sys
->
i_order_length
)
i_real_index
=
++
i_greatest_real_index_used
;
}
i_row
=
(
i_real_index
/
p_sys
->
i_cols
)
%
p_sys
->
i_rows
;
i_col
=
i_real_index
%
p_sys
->
i_cols
;
if
(
!
p_sys
->
b_keep
)
if
(
!
p_sys
->
b_keep
)
{
/* Convert the images */
fmt_in
.
i_chroma
=
p_
pic
->
p_picture
->
format
.
i_chroma
;
fmt_in
.
i_height
=
p_
pic
->
p_picture
->
format
.
i_height
;
fmt_in
.
i_width
=
p_
pic
->
p_picture
->
format
.
i_width
;
fmt_in
.
i_chroma
=
p_
es
->
p_picture
->
format
.
i_chroma
;
fmt_in
.
i_height
=
p_
es
->
p_picture
->
format
.
i_height
;
fmt_in
.
i_width
=
p_
es
->
p_picture
->
format
.
i_width
;
fmt_out
.
i_chroma
=
VLC_FOURCC
(
'Y'
,
'U'
,
'V'
,
'A'
);
fmt_out
.
i_width
=
fmt_in
.
i_width
*
...
...
@@ -457,42 +456,19 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
>
(
float
)
fmt_in
.
i_width
/
(
float
)
fmt_in
.
i_height
)
{
fmt_out
.
i_width
=
(
fmt_out
.
i_height
*
fmt_in
.
i_width
)
/
fmt_in
.
i_height
;
/
fmt_in
.
i_height
;
}
else
{
fmt_out
.
i_height
=
(
fmt_out
.
i_width
*
fmt_in
.
i_height
)
/
fmt_in
.
i_width
;
/
fmt_in
.
i_width
;
}
}
fmt_out
.
i_visible_width
=
fmt_out
.
i_width
;
fmt_out
.
i_visible_height
=
fmt_out
.
i_height
;
#ifdef IMAGE_2PASSES
fmt_middle
.
i_chroma
=
fmt_in
.
i_chroma
;
fmt_middle
.
i_visible_width
=
fmt_middle
.
i_width
=
fmt_out
.
i_width
;
fmt_middle
.
i_visible_height
=
fmt_middle
.
i_height
=
fmt_out
.
i_height
;
p_middle
=
image_Convert
(
p_sys
->
p_image2
,
p_pic
->
p_picture
,
&
fmt_in
,
&
fmt_middle
);
if
(
!
p_middle
)
{
msg_Warn
(
p_filter
,
"image resizing failed"
);
continue
;
}
p_converted
=
image_Convert
(
p_sys
->
p_image
,
p_middle
,
&
fmt_middle
,
&
fmt_out
);
p_middle
->
pf_release
(
p_middle
);
if
(
!
p_converted
)
{
msg_Warn
(
p_filter
,
"image chroma conversion failed"
);
continue
;
}
#else
p_converted
=
image_Convert
(
p_sys
->
p_image
,
p_pic
->
p_picture
,
p_converted
=
image_Convert
(
p_sys
->
p_image
,
p_es
->
p_picture
,
&
fmt_in
,
&
fmt_out
);
if
(
!
p_converted
)
{
...
...
@@ -500,11 +476,10 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
"image resizing and chroma conversion failed"
);
continue
;
}
#endif
}
else
{
p_converted
=
p_
pic
->
p_picture
;
p_converted
=
p_
es
->
p_picture
;
p_converted
->
i_refcount
++
;
fmt_in
.
i_width
=
fmt_out
.
i_width
=
p_converted
->
format
.
i_width
;
fmt_in
.
i_height
=
fmt_out
.
i_height
=
p_converted
->
format
.
i_height
;
...
...
@@ -520,8 +495,8 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
msg_Err
(
p_filter
,
"cannot allocate SPU region"
);
p_filter
->
pf_sub_buffer_del
(
p_filter
,
p_spu
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
vlc_mutex_unlock
(
lockval
.
p_address
);
return
NULL
;
vlc_mutex_unlock
(
p_sys
->
p_lock
);
return
p_spu
;
}
/* HACK ALERT : let's fix the pointers to avoid picture duplication.
...
...
@@ -578,8 +553,8 @@ static subpicture_t *Filter( filter_t *p_filter, mtime_t date )
p_region_prev
=
p_region
;
}
vlc_mutex_unlock
(
p_sys
->
p_lock
);
vlc_mutex_unlock
(
&
p_sys
->
lock
);
vlc_mutex_unlock
(
lockval
.
p_address
);
return
p_spu
;
}
...
...
modules/video_
output/picture
.h
→
modules/video_
filter/mosaic
.h
View file @
f976d6ae
/*****************************************************************************
*
picture
.h:
*
mosaic
.h:
*****************************************************************************
* Copyright (C) 2004-2005 VideoLAN
* $Id$
*
* Authors: Antoine Cellerier <dionoea@videolan.org>
* Christophe Massiot <massiot@via.ecp.fr>
*
* 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
...
...
@@ -21,24 +22,37 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
#ifndef _PICTURE_VOUT_H
#define _PICTURE_VOUT_H 1
#define PICTURE_VOUT_E_AVAILABLE 0
#define PICTURE_VOUT_E_OCCUPIED 1
typedef
struct
picture_vout_e_t
typedef
struct
bridged_es_t
{
es_format_t
fmt
;
picture_t
*
p_picture
;
int
i_status
;
picture_t
**
pp_last
;
vlc_bool_t
b_empty
;
char
*
psz_id
;
}
picture_vout_e_t
;
}
bridged_es_t
;
typedef
struct
bridge_t
{
bridged_es_t
**
pp_es
;
int
i_es_num
;
}
bridge_t
;
typedef
struct
picture_vout_t
#define GetBridge(a) __GetBridge( VLC_OBJECT(a) )
static
bridge_t
*
__GetBridge
(
vlc_object_t
*
p_object
)
{
int
i_picture_num
;
picture_vout_e_t
*
p_pic
;
}
picture_vout_t
;
libvlc_t
*
p_libvlc
=
p_object
->
p_libvlc
;
bridge_t
*
p_bridge
;
vlc_value_t
val
;
if
(
var_Get
(
p_libvlc
,
"mosaic-struct"
,
&
val
)
!=
VLC_SUCCESS
)
{
p_bridge
=
NULL
;
}
else
{
p_bridge
=
val
.
p_address
;
}
#undef IMAGE_2PASSES
return
p_bridge
;
}
#endif
modules/video_output/Modules.am
View file @
f976d6ae
...
...
@@ -12,5 +12,3 @@ SOURCES_hd1000v = hd1000v.cpp
SOURCES_snapshot = snapshot.c
SOURCES_opengl = opengl.c
SOURCES_image = image.c
SOURCES_picture = picture.h \
picture.c
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