Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-gpu
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-gpu
Commits
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