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
73cd72e3
Commit
73cd72e3
authored
Jun 06, 2009
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converted wall to "video splitter".
parent
d0967dc4
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
273 additions
and
493 deletions
+273
-493
modules/video_filter/wall.c
modules/video_filter/wall.c
+268
-493
modules/video_filter/wrapper.c
modules/video_filter/wrapper.c
+5
-0
No files found.
modules/video_filter/wall.c
View file @
73cd72e3
/*****************************************************************************
/*****************************************************************************
* wall.c : Wall video plugin for vlc
* wall.c : Wall video plugin for vlc
*****************************************************************************
*****************************************************************************
* Copyright (C) 2000
, 2001, 2002, 2003
the VideoLAN team
* Copyright (C) 2000
-2009
the VideoLAN team
* $Id$
* $Id$
*
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Authors: Samuel Hocevar <sam@zoy.org>
...
@@ -28,32 +28,14 @@
...
@@ -28,32 +28,14 @@
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include "config.h"
# include "config.h"
#endif
#endif
#include <assert.h>
#include <vlc_common.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_plugin.h>
#include <vlc_vout.h>
#include "vlc_video_splitter.h"
#include <assert.h>
#include "filter_common.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
);
static
void
Destroy
(
vlc_object_t
*
);
static
int
Init
(
vout_thread_t
*
);
static
void
End
(
vout_thread_t
*
);
static
void
Render
(
vout_thread_t
*
,
picture_t
*
);
static
void
RemoveAllVout
(
vout_thread_t
*
p_vout
);
/* FIXME it is needed for VOUT_ALIGN_* only */
#include <vlc_vout.h>
static
int
MouseEvent
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
static
int
FullscreenEventUp
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
static
int
FullscreenEventDown
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
/*****************************************************************************
/*****************************************************************************
* Module descriptor
* Module descriptor
...
@@ -76,10 +58,13 @@ static int FullscreenEventDown( vlc_object_t *, char const *,
...
@@ -76,10 +58,13 @@ static int FullscreenEventDown( vlc_object_t *, char const *,
#define CFG_PREFIX "wall-"
#define CFG_PREFIX "wall-"
vlc_module_begin
()
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
vlc_module_begin
()
set_description
(
N_
(
"Wall video filter"
)
)
set_description
(
N_
(
"Wall video filter"
)
)
set_shortname
(
N_
(
"Image wall"
))
set_shortname
(
N_
(
"Image wall"
))
set_capability
(
"video
fil
ter"
,
0
)
set_capability
(
"video
split
ter"
,
0
)
set_category
(
CAT_VIDEO
)
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VFILTER
)
set_subcategory
(
SUBCAT_VIDEO_VFILTER
)
...
@@ -90,575 +75,365 @@ vlc_module_begin ()
...
@@ -90,575 +75,365 @@ vlc_module_begin ()
add_string
(
CFG_PREFIX
"element-aspect"
,
"4:3"
,
NULL
,
ASPECT_TEXT
,
ASPECT_LONGTEXT
,
false
)
add_string
(
CFG_PREFIX
"element-aspect"
,
"4:3"
,
NULL
,
ASPECT_TEXT
,
ASPECT_LONGTEXT
,
false
)
add_shortcut
(
"wall"
)
add_shortcut
(
"wall"
)
set_callbacks
(
Create
,
Destroy
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
vlc_module_end
()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
const
char
*
const
ppsz_filter_options
[]
=
{
static
const
char
*
const
ppsz_filter_options
[]
=
{
"cols"
,
"rows"
,
"active"
,
"element-aspect"
,
NULL
"cols"
,
"rows"
,
"active"
,
"element-aspect"
,
NULL
};
};
/*****************************************************************************
/* */
* vout_sys_t: Wall video output method descriptor
typedef
struct
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the Wall specific properties of an output thread.
*****************************************************************************/
struct
vout_sys_t
{
{
int
i_col
;
bool
b_active
;
int
i_row
;
int
i_output
;
int
i_vout
;
int
i_width
;
struct
vout_list_t
int
i_height
;
{
int
i_align
;
bool
b_active
;
int
i_left
;
int
i_width
;
int
i_top
;
int
i_height
;
}
wall_output_t
;
int
i_left
;
int
i_top
;
#define ROW_MAX (15)
vout_thread_t
*
p_vout
;
#define COL_MAX (15)
}
*
pp_vout
;
struct
video_splitter_sys_t
};
/*****************************************************************************
* Control: control facility for the vout (forwards to child vout)
*****************************************************************************/
static
int
Control
(
vout_thread_t
*
p_vout
,
int
i_query
,
va_list
args
)
{
{
int
i_row
,
i_col
,
i_vout
=
0
;
int
i_col
;
int
i_row
;
int
i_output
;
wall_output_t
pp_output
[
ROW_MAX
][
COL_MAX
];
/* [x][y] */
};
for
(
i_row
=
0
;
i_row
<
p_vout
->
p_sys
->
i_row
;
i_row
++
)
static
int
Filter
(
video_splitter_t
*
,
picture_t
*
pp_dst
[],
picture_t
*
);
{
static
int
Mouse
(
video_splitter_t
*
,
vlc_mouse_t
*
,
for
(
i_col
=
0
;
i_col
<
p_vout
->
p_sys
->
i_col
;
i_col
++
)
int
i_index
,
{
const
vlc_mouse_t
*
p_old
,
const
vlc_mouse_t
*
p_new
);
vout_vaControl
(
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
p_vout
,
i_query
,
args
);
i_vout
++
;
}
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
/**
* Create: allocates Wall video thread output method
* This function allocates and initializes a Wall splitter module.
*****************************************************************************
*/
* This function allocates and initializes a Wall vout method.
static
int
Open
(
vlc_object_t
*
p_this
)
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
p_this
)
{
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
video_splitter_t
*
p_splitter
=
(
video_splitter_t
*
)
p_this
;
char
*
psz_method
,
*
psz_tmp
,
*
psz_method_tmp
;
video_splitter_sys_t
*
p_sys
;
int
i_vout
;
/* Allocate structure */
p_splitter
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
*
p_sys
)
);
p_vout
->
p_sys
=
malloc
(
sizeof
(
vout_sys_t
)
);
if
(
!
p_sys
)
if
(
p_vout
->
p_sys
==
NULL
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
p_vout
->
pf_init
=
Init
;
config_ChainParse
(
p_splitter
,
CFG_PREFIX
,
ppsz_filter_options
,
p_vout
->
pf_end
=
End
;
p_splitter
->
p_cfg
);
p_vout
->
pf_manage
=
NULL
;
p_vout
->
pf_render
=
Render
;
p_vout
->
pf_display
=
NULL
;
p_vout
->
pf_control
=
Control
;
config_ChainParse
(
p_vout
,
CFG_PREFIX
,
ppsz_filter_options
,
p_vout
->
p_cfg
);
/*
Look what method was requested
*/
/* */
p_
vout
->
p_sys
->
i_col
=
var_CreateGetInteger
(
p_vout
,
CFG_PREFIX
"cols"
);
p_
sys
->
i_col
=
var_CreateGetInteger
(
p_splitter
,
CFG_PREFIX
"cols"
);
p_
vout
->
p_sys
->
i_row
=
var_CreateGetInteger
(
p_vout
,
CFG_PREFIX
"rows"
);
p_
sys
->
i_col
=
__MAX
(
1
,
__MIN
(
COL_MAX
,
p_sys
->
i_col
)
);
p_
vout
->
p_sys
->
i_col
=
__MAX
(
1
,
__MIN
(
15
,
p_vout
->
p_sys
->
i_col
)
);
p_
sys
->
i_row
=
var_CreateGetInteger
(
p_splitter
,
CFG_PREFIX
"rows"
);
p_
vout
->
p_sys
->
i_row
=
__MAX
(
1
,
__MIN
(
15
,
p_vout
->
p_sys
->
i_row
)
);
p_
sys
->
i_row
=
__MAX
(
1
,
__MIN
(
ROW_MAX
,
p_sys
->
i_row
)
);
msg_Dbg
(
p_
vout
,
"opening a %i x %i wall"
,
msg_Dbg
(
p_
splitter
,
"opening a %i x %i wall"
,
p_
vout
->
p_sys
->
i_col
,
p_vout
->
p_sys
->
i_row
);
p_
sys
->
i_col
,
p_sys
->
i_row
);
p_vout
->
p_sys
->
pp_vout
=
malloc
(
p_vout
->
p_sys
->
i_row
*
/* */
p_vout
->
p_sys
->
i_col
*
char
*
psz_state
=
var_CreateGetNonEmptyString
(
p_splitter
,
CFG_PREFIX
"active"
);
sizeof
(
struct
vout_list_t
)
);
if
(
p_vout
->
p_sys
->
pp_vout
==
NULL
)
{
free
(
p_vout
->
p_sys
);
return
VLC_ENOMEM
;
}
psz_method_tmp
=
/* */
psz_method
=
var_CreateGetNonEmptyString
(
p_vout
,
CFG_PREFIX
"active"
);
bool
pb_active
[
COL_MAX
*
ROW_MAX
];
for
(
int
i
=
0
;
i
<
COL_MAX
*
ROW_MAX
;
i
++
)
pb_active
[
i
]
=
psz_state
==
NULL
;
/* If no trailing vout are specified, take them all */
/* Parse active list if provided */
if
(
psz_method
==
NULL
)
char
*
psz_tmp
=
psz_state
;
{
while
(
psz_tmp
&&
*
psz_tmp
)
for
(
i_vout
=
p_vout
->
p_sys
->
i_row
*
p_vout
->
p_sys
->
i_col
;
i_vout
--
;
)
{
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
b_active
=
1
;
}
}
/* If trailing vout are specified, activate only the requested ones */
else
{
{
for
(
i_vout
=
p_vout
->
p_sys
->
i_row
*
p_vout
->
p_sys
->
i_col
;
char
*
psz_next
=
strchr
(
psz_tmp
,
','
);
i_vout
--
;
)
if
(
psz_next
)
{
*
psz_next
++
=
'\0'
;
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
b_active
=
0
;
}
while
(
*
psz_method
)
const
int
i_index
=
atoi
(
psz_tmp
);
{
if
(
i_index
>=
0
&&
i_index
<
COL_MAX
*
ROW_MAX
)
psz_tmp
=
psz_method
;
pb_active
[
i_index
]
=
true
;
while
(
*
psz_tmp
&&
*
psz_tmp
!=
','
)
{
psz_tmp
++
;
}
if
(
*
psz_tmp
)
{
*
psz_tmp
=
'\0'
;
i_vout
=
atoi
(
psz_method
);
psz_method
=
psz_tmp
+
1
;
}
else
{
i_vout
=
atoi
(
psz_method
);
psz_method
=
psz_tmp
;
}
if
(
i_vout
>=
0
&&
i_vout
<
p_vout
->
p_sys
->
i_row
*
p_vout
->
p_sys
->
i_col
)
{
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
b_active
=
1
;
}
}
}
}
free
(
psz_state
);
free
(
psz_method_tmp
);
/* Parse aspect ratio if provided */
int
i_aspect
=
0
;
return
VLC_SUCCESS
;
char
*
psz_aspect
=
var_CreateGetNonEmptyString
(
p_splitter
,
}
CFG_PREFIX
"element-aspect"
);
if
(
psz_aspect
)
/*****************************************************************************
* Init: initialize Wall video thread output method
*****************************************************************************/
static
int
Init
(
vout_thread_t
*
p_vout
)
{
int
i_row
,
i_col
,
i_width
,
i_height
,
i_left
,
i_top
;
unsigned
int
i_target_width
,
i_target_height
;
video_format_t
fmt
;
int
i_aspect
=
4
*
VOUT_ASPECT_FACTOR
/
3
;
int
i_align
=
0
;
unsigned
int
i_hstart
,
i_hend
,
i_vstart
,
i_vend
;
unsigned
int
w1
,
h1
,
w2
,
h2
;
int
i_xpos
,
i_ypos
;
int
i_vstart_rounded
=
0
,
i_hstart_rounded
=
0
;
char
*
psz_aspect
;
memset
(
&
fmt
,
0
,
sizeof
(
video_format_t
)
);
psz_aspect
=
var_CreateGetNonEmptyString
(
p_vout
,
CFG_PREFIX
"element-aspect"
);
if
(
psz_aspect
&&
*
psz_aspect
)
{
{
char
*
psz_parser
=
strchr
(
psz_aspect
,
':'
);
int
i_ar_num
,
i_ar_den
;
if
(
psz_parser
)
if
(
sscanf
(
psz_aspect
,
"%d:%d"
,
&
i_ar_num
,
&
i_ar_den
)
==
2
&&
i_ar_num
>
0
&&
i_ar_den
>
0
)
{
{
*
psz_parser
++
=
'\0'
;
i_aspect
=
i_ar_num
*
VOUT_ASPECT_FACTOR
/
i_ar_den
;
i_aspect
=
atoi
(
psz_aspect
)
*
VOUT_ASPECT_FACTOR
/
atoi
(
psz_parser
);
}
}
else
else
{
{
msg_Warn
(
p_
vout
,
"invalid aspect ratio specification"
);
msg_Warn
(
p_
splitter
,
"invalid aspect ratio specification"
);
}
}
free
(
psz_aspect
);
}
}
free
(
psz_aspect
);
if
(
i_aspect
<=
0
)
i_aspect
=
4
*
VOUT_ASPECT_FACTOR
/
3
;
i_xpos
=
var_CreateGetInteger
(
p_vout
,
"video-x"
);
i_ypos
=
var_CreateGetInteger
(
p_vout
,
"video-y"
);
/* Compute placements/size of the windows */
if
(
i_xpos
<
0
)
i_xpos
=
0
;
const
unsigned
w1
=
(
p_splitter
->
fmt
.
i_width
/
p_sys
->
i_col
)
&
~
1
;
if
(
i_ypos
<
0
)
i_ypos
=
0
;
const
unsigned
h1
=
(
w1
*
VOUT_ASPECT_FACTOR
/
i_aspect
)
&
~
1
;
I_OUTPUTPICTURES
=
0
;
const
unsigned
h2
=
(
p_splitter
->
fmt
.
i_height
/
p_sys
->
i_row
)
&
~
1
;
const
unsigned
w2
=
(
h2
*
i_aspect
/
VOUT_ASPECT_FACTOR
)
&
~
1
;
/* Initialize the output structure */
p_vout
->
output
.
i_chroma
=
p_vout
->
render
.
i_chroma
;
unsigned
i_target_width
;
p_vout
->
output
.
i_width
=
p_vout
->
render
.
i_width
;
unsigned
i_target_height
;
p_vout
->
output
.
i_height
=
p_vout
->
render
.
i_height
;
unsigned
i_hstart
,
i_hend
;
p_vout
->
output
.
i_aspect
=
p_vout
->
render
.
i_aspect
;
unsigned
i_vstart
,
i_vend
;
var_Create
(
p_vout
,
"align"
,
VLC_VAR_INTEGER
);
bool
b_vstart_rounded
;
bool
b_hstart_rounded
;
fmt
.
i_width
=
fmt
.
i_visible_width
=
p_vout
->
render
.
i_width
;
fmt
.
i_height
=
fmt
.
i_visible_height
=
p_vout
->
render
.
i_height
;
if
(
h1
*
p_sys
->
i_row
<
p_splitter
->
fmt
.
i_height
)
fmt
.
i_x_offset
=
fmt
.
i_y_offset
=
0
;
fmt
.
i_chroma
=
p_vout
->
render
.
i_chroma
;
fmt
.
i_aspect
=
p_vout
->
render
.
i_aspect
;
fmt
.
i_sar_num
=
p_vout
->
render
.
i_aspect
*
fmt
.
i_height
/
fmt
.
i_width
;
fmt
.
i_sar_den
=
VOUT_ASPECT_FACTOR
;
w1
=
p_vout
->
output
.
i_width
/
p_vout
->
p_sys
->
i_col
;
w1
&=
~
1
;
h1
=
w1
*
VOUT_ASPECT_FACTOR
/
i_aspect
&~
1
;
h1
&=
~
1
;
h2
=
p_vout
->
output
.
i_height
/
p_vout
->
p_sys
->
i_row
&~
1
;
h2
&=
~
1
;
w2
=
h2
*
i_aspect
/
VOUT_ASPECT_FACTOR
&~
1
;
w2
&=
~
1
;
if
(
h1
*
p_vout
->
p_sys
->
i_row
<
p_vout
->
output
.
i_height
)
{
{
unsigned
int
i_tmp
;
i_target_width
=
w2
;
i_target_width
=
w2
;
i_target_height
=
h2
;
i_target_height
=
h2
;
i_vstart
=
0
;
i_vstart
=
0
;
i_vend
=
p_vout
->
output
.
i_height
;
b_vstart_rounded
=
false
;
i_tmp
=
i_target_width
*
p_vout
->
p_sys
->
i_col
;
i_vend
=
p_splitter
->
fmt
.
i_height
;
while
(
i_tmp
<
p_vout
->
output
.
i_width
)
i_tmp
+=
p_vout
->
p_sys
->
i_col
;
i_hstart
=
((
i_tmp
-
p_vout
->
output
.
i_width
)
/
2
)
&~
1
;
unsigned
i_tmp
=
i_target_width
*
p_sys
->
i_col
;
i_hstart_rounded
=
(
(
i_tmp
-
p_vout
->
output
.
i_width
)
%
2
)
||
while
(
i_tmp
<
p_splitter
->
fmt
.
i_width
)
(
(
(
i_tmp
-
p_vout
->
output
.
i_width
)
/
2
)
&
1
);
i_tmp
+=
p_sys
->
i_col
;
i_hend
=
i_hstart
+
p_vout
->
output
.
i_width
;
i_hstart
=
((
i_tmp
-
p_splitter
->
fmt
.
i_width
)
/
2
)
&~
1
;
b_hstart_rounded
=
(
(
i_tmp
-
p_splitter
->
fmt
.
i_width
)
%
2
)
||
(
(
(
i_tmp
-
p_splitter
->
fmt
.
i_width
)
/
2
)
&
1
);
i_hend
=
i_hstart
+
p_splitter
->
fmt
.
i_width
;
}
}
else
else
{
{
unsigned
int
i_tmp
;
i_target_height
=
h1
;
i_target_height
=
h1
;
i_target_width
=
w1
;
i_target_width
=
w1
;
i_hstart
=
0
;
i_hend
=
p_vout
->
output
.
i_width
;
i_tmp
=
i_target_height
*
p_vout
->
p_sys
->
i_row
;
while
(
i_tmp
<
p_vout
->
output
.
i_height
)
i_tmp
+=
p_vout
->
p_sys
->
i_row
;
i_vstart
=
(
(
i_tmp
-
p_vout
->
output
.
i_height
)
/
2
)
&
~
1
;
i_vstart_rounded
=
(
(
i_tmp
-
p_vout
->
output
.
i_height
)
%
2
)
||
(
(
(
i_tmp
-
p_vout
->
output
.
i_height
)
/
2
)
&
1
);
i_vend
=
i_vstart
+
p_vout
->
output
.
i_height
;
}
msg_Dbg
(
p_vout
,
"target resolution %dx%d"
,
i_target_width
,
i_target_height
);
/* Try to open the real video output */
i_hstart
=
0
;
msg_Dbg
(
p_vout
,
"spawning the real video outputs"
);
b_hstart_rounded
=
false
;
i_hend
=
p_splitter
->
fmt
.
i_width
;
p_vout
->
p_sys
->
i_vout
=
0
;
unsigned
i_tmp
=
i_target_height
*
p_sys
->
i_row
;
msg_Dbg
(
p_vout
,
"target window (%d,%d)-(%d,%d)"
,
i_hstart
,
i_vstart
,
i_hend
,
i_vend
);
while
(
i_tmp
<
p_splitter
->
fmt
.
i_height
)
i_tmp
+=
p_sys
->
i_row
;
i_vstart
=
(
(
i_tmp
-
p_splitter
->
fmt
.
i_height
)
/
2
)
&
~
1
;
b_vstart_rounded
=
(
(
i_tmp
-
p_splitter
->
fmt
.
i_height
)
%
2
)
||
(
(
(
i_tmp
-
p_splitter
->
fmt
.
i_height
)
/
2
)
&
1
);
i_vend
=
i_vstart
+
p_splitter
->
fmt
.
i_height
;
}
msg_Dbg
(
p_splitter
,
"target resolution %dx%d"
,
i_target_width
,
i_target_height
);
msg_Dbg
(
p_splitter
,
"target window (%d,%d)-(%d,%d)"
,
i_hstart
,
i_vstart
,
i_hend
,
i_vend
);
i_top
=
0
;
int
i_active
=
0
;
i_height
=
0
;
for
(
int
y
=
0
,
i_top
=
0
;
y
<
p_sys
->
i_row
;
y
++
)
for
(
i_row
=
0
;
i_row
<
p_vout
->
p_sys
->
i_row
;
i_row
++
)
{
{
i_left
=
0
;
/* */
i_top
+=
i_height
;
int
i_height
=
0
;
for
(
i_col
=
0
;
i_col
<
p_vout
->
p_sys
->
i_col
;
i_col
++
)
int
i_halign
=
0
;
if
(
y
*
i_target_height
>=
i_vstart
&&
(
y
+
1
)
*
i_target_height
<=
i_vend
)
{
{
i_align
=
0
;
i_height
=
i_target_height
;
}
if
(
i_col
*
i_target_width
>=
i_hstart
&&
else
if
(
(
y
+
1
)
*
i_target_height
<
i_vstart
||
(
i_col
+
1
)
*
i_target_width
<=
i_hend
)
(
y
*
i_target_height
)
>
i_vend
)
{
{
i_width
=
i_target_width
;
i_height
=
0
;
}
}
else
if
(
(
i_col
+
1
)
*
i_target_width
<
i_hstart
||
else
(
i_col
*
i_target_width
)
>
i_hend
)
{
i_height
=
(
i_target_height
-
i_vstart
%
i_target_height
);
if
(
y
>=
(
p_sys
->
i_row
/
2
)
)
{
{
i_width
=
0
;
i_halign
=
VOUT_ALIGN_TOP
;
i_height
-=
b_vstart_rounded
?
2
:
0
;
}
}
else
else
{
{
i_width
=
(
i_target_width
-
i_hstart
%
i_target_width
);
i_halign
=
VOUT_ALIGN_BOTTOM
;
if
(
i_col
>=
(
p_vout
->
p_sys
->
i_col
/
2
)
)
{
i_align
|=
VOUT_ALIGN_LEFT
;
i_width
-=
i_hstart_rounded
?
2
:
0
;
}
else
{
i_align
|=
VOUT_ALIGN_RIGHT
;
}
}
}
}
if
(
i_row
*
i_target_height
>=
i_vstart
&&
/* */
(
i_row
+
1
)
*
i_target_height
<=
i_vend
)
for
(
int
x
=
0
,
i_left
=
0
;
x
<
p_sys
->
i_col
;
x
++
)
{
wall_output_t
*
p_output
=
&
p_sys
->
pp_output
[
x
][
y
];
/* */
int
i_width
;
int
i_valign
=
0
;
if
(
x
*
i_target_width
>=
i_hstart
&&
(
x
+
1
)
*
i_target_width
<=
i_hend
)
{
{
i_
height
=
i_target_height
;
i_
width
=
i_target_width
;
}
}
else
if
(
(
i_row
+
1
)
*
i_target_height
<
i_v
start
||
else
if
(
(
x
+
1
)
*
i_target_width
<
i_h
start
||
(
i_row
*
i_target_height
)
>
i_v
end
)
(
x
*
i_target_width
)
>
i_h
end
)
{
{
i_
height
=
0
;
i_
width
=
0
;
}
}
else
else
{
{
i_height
=
(
i_target_height
-
i_width
=
(
i_target_width
-
i_hstart
%
i_target_width
);
i_vstart
%
i_target_height
);
if
(
x
>=
(
p_sys
->
i_col
/
2
)
)
if
(
i_row
>=
(
p_vout
->
p_sys
->
i_row
/
2
)
)
{
{
i_
align
|=
VOUT_ALIGN_TOP
;
i_
valign
=
VOUT_ALIGN_LEFT
;
i_
height
-=
i_v
start_rounded
?
2
:
0
;
i_
width
-=
b_h
start_rounded
?
2
:
0
;
}
}
else
else
{
{
i_
align
|=
VOUT_ALIGN_BOTTOM
;
i_
valign
=
VOUT_ALIGN_RIGHT
;
}
}
}
}
if
(
i_height
==
0
||
i_width
==
0
)
{
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
b_active
=
false
;
}
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
i_width
=
i_width
;
/* */
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
i_height
=
i_height
;
p_output
->
b_active
=
pb_active
[
y
*
p_sys
->
i_col
+
x
]
&&
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
i_left
=
i_left
;
i_height
>
0
&&
i_width
>
0
;
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
i_top
=
i_top
;
p_output
->
i_output
=
-
1
;
p_output
->
i_align
=
i_valign
|
i_halign
;
p_output
->
i_width
=
i_width
;
p_output
->
i_height
=
i_height
;
p_output
->
i_left
=
i_left
;
p_output
->
i_top
=
i_top
;
msg_Dbg
(
p_splitter
,
"window %dx%d at %d:%d size %dx%d"
,
x
,
y
,
i_left
,
i_top
,
i_width
,
i_height
);
if
(
p_output
->
b_active
)
i_active
++
;
i_left
+=
i_width
;
i_left
+=
i_width
;
}
i_top
+=
i_height
;
}
if
(
i_active
<=
0
)
{
msg_Err
(
p_splitter
,
"No active video output"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
if
(
!
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
b_active
)
/* Setup output configuration */
{
p_splitter
->
i_output
=
i_active
;
p_vout
->
p_sys
->
i_vout
++
;
p_splitter
->
p_output
=
calloc
(
p_splitter
->
i_output
,
sizeof
(
*
p_splitter
->
p_output
)
);
if
(
!
p_splitter
->
p_output
)
{
free
(
p_sys
);
return
VLC_ENOMEM
;
}
for
(
int
y
=
0
,
i_output
=
0
;
y
<
p_sys
->
i_row
;
y
++
)
{
for
(
int
x
=
0
;
x
<
p_sys
->
i_col
;
x
++
)
{
wall_output_t
*
p_output
=
&
p_sys
->
pp_output
[
x
][
y
];
if
(
!
p_output
->
b_active
)
continue
;
continue
;
}
var_SetInteger
(
p_vout
,
"align"
,
i_align
);
p_output
->
i_output
=
i_output
++
;
var_SetInteger
(
p_vout
,
"video-x"
,
i_left
+
i_xpos
-
i_width
);
var_SetInteger
(
p_vout
,
"video-y"
,
i_top
+
i_ypos
);
video_splitter_output_t
*
p_cfg
=
&
p_splitter
->
p_output
[
p_output
->
i_output
];
fmt
.
i_width
=
fmt
.
i_visible_width
=
i_width
;
video_format_Copy
(
&
p_cfg
->
fmt
,
&
p_splitter
->
fmt
);
fmt
.
i_height
=
fmt
.
i_visible_height
=
i_height
;
p_cfg
->
fmt
.
i_visible_width
=
fmt
.
i_aspect
=
i_aspect
*
i_target_height
/
i_height
*
p_cfg
->
fmt
.
i_width
=
p_output
->
i_width
;
i_width
/
i_target_width
;
p_cfg
->
fmt
.
i_visible_height
=
p_cfg
->
fmt
.
i_height
=
p_output
->
i_height
;
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
p_vout
=
p_cfg
->
fmt
.
i_aspect
=
(
int64_t
)
i_aspect
*
i_target_height
*
p_output
->
i_width
/
i_target_width
/
p_output
->
i_height
;
vout_Create
(
p_vout
,
&
fmt
);
if
(
!
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
p_vout
)
p_cfg
->
window
.
i_x
=
p_output
->
i_left
;
/* FIXME relative to video-x/y (TODO in wrapper.c) ? */
{
p_cfg
->
window
.
i_y
=
p_output
->
i_top
;
msg_Err
(
p_vout
,
"failed to get %ix%i vout threads"
,
p_cfg
->
window
.
i_align
=
p_output
->
i_align
;
p_vout
->
p_sys
->
i_col
,
p_vout
->
p_sys
->
i_row
);
p_cfg
->
psz_module
=
NULL
;
RemoveAllVout
(
p_vout
);
return
VLC_EGENERIC
;
}
vout_filter_SetupChild
(
p_vout
,
p_vout
->
p_sys
->
pp_vout
[
p_vout
->
p_sys
->
i_vout
].
p_vout
,
MouseEvent
,
FullscreenEventUp
,
FullscreenEventDown
,
true
);
p_vout
->
p_sys
->
i_vout
++
;
}
}
}
}
vout_filter_AllocateDirectBuffers
(
p_vout
,
VOUT_MAX_PICTURES
);
/* */
p_splitter
->
pf_filter
=
Filter
;
p_splitter
->
pf_mouse
=
Mouse
;
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
/*****************************************************************************
/**
* End: terminate Wall video thread output method
* Terminate a splitter module.
*****************************************************************************/
*/
static
void
End
(
vout_thread_t
*
p_vout
)
static
void
Close
(
vlc_object_t
*
p_this
)
{
RemoveAllVout
(
p_vout
);
vout_filter_ReleaseDirectBuffers
(
p_vout
);
}
/*****************************************************************************
* Destroy: destroy Wall video thread output method
*****************************************************************************
* Terminate an output method created by WallCreateOutputMethod
*****************************************************************************/
static
void
Destroy
(
vlc_object_t
*
p_this
)
{
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
video_splitter_t
*
p_splitter
=
(
video_splitter_t
*
)
p_this
;
video_splitter_sys_t
*
p_sys
=
p_splitter
->
p_sys
;
free
(
p_splitter
->
p_output
);
free
(
p_vout
->
p_sys
->
pp_vout
);
free
(
p_sys
);
free
(
p_vout
->
p_sys
);
}
}
/*****************************************************************************
static
int
Filter
(
video_splitter_t
*
p_splitter
,
picture_t
*
pp_dst
[],
picture_t
*
p_src
)
* Render: displays previously rendered output
*****************************************************************************
* This function send the currently rendered image to Wall image, waits
* until it is displayed and switch the two rendering buffers, preparing next
* frame.
*****************************************************************************/
static
void
Render
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
{
picture_t
*
p_outpic
=
NULL
;
video_splitter_sys_t
*
p_sys
=
p_splitter
->
p_sys
;
int
i_col
,
i_row
,
i_vout
,
i_plane
;
int
pi_left_skip
[
VOUT_MAX_PLANES
],
pi_top_skip
[
VOUT_MAX_PLANES
];
i_vout
=
0
;
if
(
video_splitter_NewPicture
(
p_splitter
,
pp_dst
)
)
return
VLC_EGENERIC
;
for
(
i
_row
=
0
;
i_row
<
p_vout
->
p_sys
->
i_row
;
i_row
++
)
for
(
i
nt
y
=
0
;
y
<
p_sys
->
i_row
;
y
++
)
{
{
for
(
i
_col
=
0
;
i_col
<
p_vout
->
p_sys
->
i_col
;
i_col
++
)
for
(
i
nt
x
=
0
;
x
<
p_sys
->
i_col
;
x
++
)
{
{
for
(
i_plane
=
0
;
i_plane
<
p_pic
->
i_planes
;
i_plane
++
)
wall_output_t
*
p_output
=
&
p_sys
->
pp_output
[
x
][
y
];
{
if
(
!
p_output
->
b_active
)
pi_left_skip
[
i_plane
]
=
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
i_left
*
p_pic
->
p
[
i_plane
].
i_pitch
/
p_vout
->
output
.
i_width
;
pi_top_skip
[
i_plane
]
=
(
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
i_top
*
p_pic
->
p
[
i_plane
].
i_lines
/
p_vout
->
output
.
i_height
)
*
p_pic
->
p
[
i_plane
].
i_pitch
;
}
if
(
!
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
b_active
)
{
i_vout
++
;
continue
;
continue
;
}
while
(
(
p_outpic
=
video_splitter_output_t
*
p_cfg
=
&
p_splitter
->
p_output
[
p_output
->
i_output
];
vout_CreatePicture
(
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
p_vout
,
picture_t
*
p_dst
=
pp_dst
[
p_output
->
i_output
];
0
,
0
,
0
)
)
==
NULL
)
{
if
(
!
vlc_object_alive
(
p_vout
)
||
p_vout
->
b_error
)
{
vout_DestroyPicture
(
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
p_vout
,
p_outpic
);
return
;
}
msleep
(
VOUT_OUTMEM_SLEEP
);
}
p_outpic
->
date
=
p_pic
->
date
;
vout_LinkPicture
(
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
p_vout
,
p_outpic
);
for
(
i_plane
=
0
;
i_plane
<
p_pic
->
i_planes
;
i_plane
++
)
/* */
picture_t
tmp
=
*
p_src
;
for
(
int
i
=
0
;
i
<
tmp
.
i_planes
;
i
++
)
{
{
uint8_t
*
p_in
,
*
p_in_end
,
*
p_out
;
plane_t
*
p0
=
&
tmp
.
p
[
0
];
int
i_in_pitch
=
p_pic
->
p
[
i_plane
].
i_pitch
;
plane_t
*
p
=
&
tmp
.
p
[
i
];
int
i_out_pitch
=
p_outpic
->
p
[
i_plane
].
i_pitch
;
const
int
i_y
=
p_output
->
i_top
*
p
->
i_visible_pitch
/
p0
->
i_visible_pitch
;
int
i_copy_pitch
=
p_outpic
->
p
[
i_plane
].
i_visible_pitch
;
const
int
i_x
=
p_output
->
i_left
*
p
->
i_visible_lines
/
p0
->
i_visible_lines
;
p_in
=
p_pic
->
p
[
i_plane
].
p_pixels
+
pi_top_skip
[
i_plane
]
+
pi_left_skip
[
i_plane
];
p_in_end
=
p_in
+
p_outpic
->
p
[
i_plane
].
i_visible_lines
*
p_pic
->
p
[
i_plane
].
i_pitch
;
p_out
=
p_outpic
->
p
[
i_plane
].
p_pixels
;
while
(
p_in
<
p_in_end
)
{
vlc_memcpy
(
p_out
,
p_in
,
i_copy_pitch
);
p_in
+=
i_in_pitch
;
p_out
+=
i_out_pitch
;
}
// pi_left_skip[i_plane] += i_copy_pitch
;
p
->
p_pixels
+=
i_y
*
p
->
i_pitch
+
(
i_x
-
(
i_x
%
p
->
i_pixel_pitch
))
;
}
}
picture_Copy
(
p_dst
,
&
tmp
);
vout_UnlinkPicture
(
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
p_vout
,
p_outpic
);
vout_DisplayPicture
(
p_vout
->
p_sys
->
pp_vout
[
i_vout
].
p_vout
,
p_outpic
);
i_vout
++
;
}
}
/* for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) */
/* { */
/* pi_top_skip[i_plane] += p_vout->p_sys->pp_vout[ i_vout ].i_height */
/* * p_pic->p[i_plane].i_visible_lines */
/* / p_vout->output.i_height */
/* * p_pic->p[i_plane].i_pitch; */
/* } */
}
}
}
/*****************************************************************************
* RemoveAllVout: destroy all the child video output threads
*****************************************************************************/
static
void
RemoveAllVout
(
vout_thread_t
*
p_vout
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
while
(
p_sys
->
i_vout
)
picture_Release
(
p_src
);
{
p_sys
->
i_vout
--
;
if
(
p_sys
->
pp_vout
[
p_sys
->
i_vout
].
b_active
)
{
vout_filter_SetupChild
(
p_vout
,
p_sys
->
pp_vout
[
p_sys
->
i_vout
].
p_vout
,
MouseEvent
,
FullscreenEventUp
,
FullscreenEventDown
,
false
);
vout_CloseAndRelease
(
p_sys
->
pp_vout
[
p_sys
->
i_vout
].
p_vout
);
}
}
}
/**
* Forward mouse event with proper conversion.
*/
static
int
MouseEvent
(
vlc_object_t
*
p_this
,
char
const
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
vout_thread_t
*
p_vout
=
p_data
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
VLC_UNUSED
(
oldval
);
int
i_vout
;
/* Find the video output index */
for
(
i_vout
=
0
;
i_vout
<
p_sys
->
i_vout
;
i_vout
++
)
{
if
(
p_sys
->
pp_vout
[
i_vout
].
b_active
&&
p_this
==
VLC_OBJECT
(
p_sys
->
pp_vout
[
i_vout
].
p_vout
)
)
break
;
}
assert
(
i_vout
<
p_vout
->
p_sys
->
i_vout
);
/* Translate the mouse coordinates */
if
(
!
strcmp
(
psz_var
,
"mouse-x"
)
)
newval
.
i_int
+=
p_vout
->
output
.
i_width
*
(
i_vout
%
p_sys
->
i_col
)
/
p_sys
->
i_col
;
else
if
(
!
strcmp
(
psz_var
,
"mouse-y"
)
)
newval
.
i_int
+=
p_vout
->
output
.
i_height
*
(
i_vout
/
p_sys
->
i_row
)
/
p_sys
->
i_row
;
return
var_Set
(
p_vout
,
psz_var
,
newval
);
}
/**
* Forward fullscreen event to/from the childrens.
*/
static
bool
IsFullscreenActive
(
vout_thread_t
*
p_vout
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
for
(
int
i
=
0
;
i
<
p_sys
->
i_vout
;
i
++
)
{
if
(
p_sys
->
pp_vout
[
i
].
b_active
&&
var_GetBool
(
p_sys
->
pp_vout
[
i
].
p_vout
,
"fullscreen"
)
)
return
true
;
}
return
false
;
}
static
int
FullscreenEventUp
(
vlc_object_t
*
p_this
,
char
const
*
psz_var
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
{
vout_thread_t
*
p_vout
=
p_data
;
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
p_this
);
VLC_UNUSED
(
psz_var
);
VLC_UNUSED
(
newval
);
const
bool
b_fullscreen
=
IsFullscreenActive
(
p_vout
);
if
(
!
var_GetBool
(
p_vout
,
"fullscreen"
)
!=
!
b_fullscreen
)
return
var_SetBool
(
p_vout
,
"fullscreen"
,
b_fullscreen
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
static
int
FullscreenEventDown
(
vlc_object_t
*
p_this
,
char
const
*
psz_var
,
static
int
Mouse
(
video_splitter_t
*
p_splitter
,
vlc_mouse_t
*
p_mouse
,
vlc_value_t
oldval
,
vlc_value_t
newval
,
void
*
p_data
)
int
i_index
,
const
vlc_mouse_t
*
p_old
,
const
vlc_mouse_t
*
p_new
)
{
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
video_splitter_sys_t
*
p_sys
=
p_splitter
->
p_sys
;
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
VLC_UNUSED
(
oldval
);
VLC_UNUSED
(
p_data
);
VLC_UNUSED
(
psz_var
);
const
bool
b_fullscreen
=
IsFullscreenActive
(
p_vout
);
for
(
int
y
=
0
;
y
<
p_sys
->
i_row
;
y
++
)
if
(
!
b_fullscreen
!=
!
newval
.
b_bool
)
{
{
for
(
int
i
=
0
;
i
<
p_sys
->
i_vout
;
i
++
)
for
(
int
x
=
0
;
x
<
p_sys
->
i_col
;
x
++
)
{
{
if
(
!
p_sys
->
pp_vout
[
i
].
b_active
)
wall_output_t
*
p_output
=
p_output
=
&
p_sys
->
pp_output
[
x
][
y
];
continue
;
if
(
p_output
->
b_active
&&
p_output
->
i_output
==
i_index
)
vout_thread_t
*
p_child
=
p_sys
->
pp_vout
[
i
].
p_vout
;
if
(
!
var_GetBool
(
p_child
,
"fullscreen"
)
!=
!
newval
.
b_bool
)
{
{
var_SetBool
(
p_child
,
"fullscreen"
,
newval
.
b_bool
);
*
p_mouse
=
*
p_new
;
if
(
newval
.
b_bool
)
p_mouse
->
i_x
+=
p_output
->
i_left
;
return
VLC_SUCCESS
;
p_mouse
->
i_y
+=
p_output
->
i_top
;
return
VLC_SUCCESS
;
}
}
}
}
}
}
return
VLC_SUCCESS
;
assert
(
0
);
return
VLC_EGENERIC
;
}
}
modules/video_filter/wrapper.c
View file @
73cd72e3
...
@@ -50,7 +50,9 @@ static void Close( vlc_object_t * );
...
@@ -50,7 +50,9 @@ static void Close( vlc_object_t * );
DECLARE_OPEN
(
magnify
,
true
)
DECLARE_OPEN
(
magnify
,
true
)
DECLARE_OPEN
(
puzzle
,
true
)
DECLARE_OPEN
(
puzzle
,
true
)
DECLARE_OPEN
(
logo
,
true
)
DECLARE_OPEN
(
logo
,
true
)
DECLARE_OPEN
(
clone
,
false
)
DECLARE_OPEN
(
clone
,
false
)
DECLARE_OPEN
(
wall
,
false
)
#undef DECLARE_OPEN
#undef DECLARE_OPEN
...
@@ -76,6 +78,9 @@ vlc_module_begin()
...
@@ -76,6 +78,9 @@ vlc_module_begin()
add_submodule
()
add_submodule
()
DECLARE_MODULE
(
clone
)
DECLARE_MODULE
(
clone
)
add_submodule
()
DECLARE_MODULE
(
wall
)
vlc_module_end
()
vlc_module_end
()
#undef DECLARE_MODULE
#undef DECLARE_MODULE
...
...
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