Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
Commits
b97a1a06
Commit
b97a1a06
authored
Jan 12, 2013
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
XCB/screen: use shared memory to reduce overhead (if available)
parent
bce10e76
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
106 additions
and
31 deletions
+106
-31
modules/access/Modules.am
modules/access/Modules.am
+2
-2
modules/access/screen/xcb.c
modules/access/screen/xcb.c
+104
-29
No files found.
modules/access/Modules.am
View file @
b97a1a06
...
...
@@ -160,9 +160,9 @@ endif
libxcb_screen_plugin_la_SOURCES = screen/xcb.c
libxcb_screen_plugin_la_CFLAGS = $(AM_CFLAGS) \
$(XCB_CFLAGS) $(XCB_COMPOSITE_CFLAGS)
$(XCB_CFLAGS) $(XCB_COMPOSITE_CFLAGS)
$(XCB_SHM_CFLAGS)
libxcb_screen_plugin_la_LIBADD = $(AM_LIBADD) \
$(XCB_LIBS) $(XCB_COMPOSITE_LIBS)
$(XCB_LIBS) $(XCB_COMPOSITE_LIBS)
$(XCB_SHM_LIBS)
if HAVE_XCB
libvlc_LTLIBRARIES += libxcb_screen_plugin.la
endif
...
...
modules/access/screen/xcb.c
View file @
b97a1a06
...
...
@@ -27,6 +27,10 @@
#include <assert.h>
#include <xcb/xcb.h>
#include <xcb/composite.h>
#ifdef HAVE_SYS_SHM_H
# include <sys/shm.h>
# include <xcb/shm.h>
#endif
#include <vlc_common.h>
#include <vlc_demux.h>
#include <vlc_plugin.h>
...
...
@@ -94,24 +98,43 @@ vlc_module_end ()
static
void
Demux
(
void
*
);
static
int
Control
(
demux_t
*
,
int
,
va_list
);
static
es_out_id_t
*
InitES
(
demux_t
*
,
uint_fast16_t
,
uint_fast16_t
,
uint_fast8_t
);
uint_fast8_t
,
uint8_t
*
);
struct
demux_sys_t
{
/* All owned by timer thread while timer is armed: */
xcb_connection_t
*
conn
;
es_out_id_t
*
es
;
float
rate
;
xcb_window_t
window
;
xcb_pixmap_t
pixmap
;
int16_t
x
,
y
;
uint16_t
w
,
h
;
uint16_t
cur_w
,
cur_h
;
xcb_connection_t
*
conn
;
/**< XCB connection */
es_out_id_t
*
es
;
/**< Window capture stream */
float
rate
;
/**< Frame rate */
xcb_window_t
window
;
/**< Captured window XID */
xcb_pixmap_t
pixmap
;
/**< Pixmap for composited capture */
xcb_shm_seg_t
segment
;
/**< SHM segment XID */
int16_t
x
,
y
;
/**< Requested capture top-left coordinates */
uint16_t
w
,
h
;
/**< Requested capture pixel dimensions */
uint8_t
bpp
;
/**< Actual bytes per pixel *es */
bool
shm
;
/**< Whether to use MIT-SHM */
bool
follow_mouse
;
uint16_t
cur_w
,
cur_h
;
/**< Actual capture pixel dimensions */
/* Timer does not use this, only input thread: */
vlc_timer_t
timer
;
};
/** Checks MIT-SHM shared memory support */
static
bool
CheckSHM
(
xcb_connection_t
*
conn
)
{
#ifdef HAVE_SYS_SHM_H
xcb_shm_query_version_cookie_t
ck
=
xcb_shm_query_version
(
conn
);
xcb_shm_query_version_reply_t
*
r
;
r
=
xcb_shm_query_version_reply
(
conn
,
ck
,
NULL
);
free
(
r
);
return
r
!=
NULL
;
#else
(
void
)
conn
;
return
false
;
#endif
}
/**
* Probes and initializes.
*/
...
...
@@ -192,6 +215,8 @@ static int Open (vlc_object_t *obj)
/* Window properties */
p_sys
->
pixmap
=
xcb_generate_id
(
conn
);
p_sys
->
segment
=
xcb_generate_id
(
conn
);
p_sys
->
shm
=
CheckSHM
(
conn
);
p_sys
->
w
=
var_InheritInteger
(
obj
,
"screen-width"
);
p_sys
->
h
=
var_InheritInteger
(
obj
,
"screen-height"
);
if
(
p_sys
->
w
!=
0
||
p_sys
->
h
!=
0
)
...
...
@@ -215,6 +240,7 @@ static int Open (vlc_object_t *obj)
p_sys
->
cur_w
=
0
;
p_sys
->
cur_h
=
0
;
p_sys
->
bpp
=
0
;
p_sys
->
es
=
NULL
;
if
(
vlc_timer_create
(
&
p_sys
->
timer
,
Demux
,
demux
))
goto
error
;
...
...
@@ -390,11 +416,12 @@ discard:
geo
->
root
,
geo
->
width
,
geo
->
height
);
}
sys
->
es
=
InitES
(
demux
,
w
,
h
,
geo
->
depth
);
sys
->
es
=
InitES
(
demux
,
w
,
h
,
geo
->
depth
,
&
sys
->
bpp
);
if
(
sys
->
es
!=
NULL
)
{
sys
->
cur_w
=
w
;
sys
->
cur_h
=
h
;
sys
->
bpp
/=
8
;
/* bits -> bytes */
}
}
...
...
@@ -403,20 +430,69 @@ discard:
(
sys
->
window
!=
geo
->
root
)
?
sys
->
pixmap
:
sys
->
window
;
free
(
geo
);
xcb_get_image_reply_t
*
img
;
img
=
xcb_get_image_reply
(
conn
,
xcb_get_image
(
conn
,
XCB_IMAGE_FORMAT_Z_PIXMAP
,
drawable
,
x
,
y
,
w
,
h
,
~
0
),
NULL
);
if
(
img
==
NULL
)
return
;
block_t
*
block
=
NULL
;
#if HAVE_SYS_SHM_H
if
(
sys
->
shm
)
{
/* Capture screen through shared memory */
size_t
size
=
w
*
h
*
sys
->
bpp
;
int
id
=
shmget
(
IPC_PRIVATE
,
size
,
IPC_CREAT
|
0777
);
if
(
id
==
-
1
)
/* XXX: fallback */
{
msg_Err
(
demux
,
"shared memory allocation error: %m"
);
goto
noshm
;
}
/* Attach the segment to X and capture */
xcb_shm_get_image_reply_t
*
img
;
xcb_shm_get_image_cookie_t
ck
;
uint8_t
*
data
=
xcb_get_image_data
(
img
);
size_t
datalen
=
xcb_get_image_data_length
(
img
);
block_t
*
block
=
block_heap_Alloc
(
img
,
data
+
datalen
-
(
uint8_t
*
)
img
);
xcb_shm_attach
(
conn
,
sys
->
segment
,
id
,
0
/* read/write */
);
ck
=
xcb_shm_get_image
(
conn
,
drawable
,
x
,
y
,
w
,
h
,
~
0
,
XCB_IMAGE_FORMAT_Z_PIXMAP
,
sys
->
segment
,
0
);
xcb_shm_detach
(
conn
,
sys
->
segment
);
img
=
xcb_shm_get_image_reply
(
conn
,
ck
,
NULL
);
xcb_flush
(
conn
);
/* ensure eventual detach */
if
(
img
==
NULL
)
{
shmctl
(
id
,
IPC_RMID
,
0
);
goto
noshm
;
}
free
(
img
);
/* Attach the segment to VLC */
void
*
shm
=
shmat
(
id
,
NULL
,
0
/* read/write */
);
shmctl
(
id
,
IPC_RMID
,
0
);
if
(
-
1
==
(
intptr_t
)
shm
)
{
msg_Err
(
demux
,
"shared memory attachment error: %m"
);
return
;
}
block
=
block_shm_Alloc
(
shm
,
size
);
if
(
unlikely
(
block
==
NULL
))
shmdt
(
shm
);
}
noshm:
#endif
if
(
block
==
NULL
)
return
;
block
->
p_buffer
=
data
;
block
->
i_buffer
=
datalen
;
{
/* Capture screen through socket (fallback) */
xcb_get_image_reply_t
*
img
;
img
=
xcb_get_image_reply
(
conn
,
xcb_get_image
(
conn
,
XCB_IMAGE_FORMAT_Z_PIXMAP
,
drawable
,
x
,
y
,
w
,
h
,
~
0
),
NULL
);
if
(
img
==
NULL
)
return
;
uint8_t
*
data
=
xcb_get_image_data
(
img
);
size_t
datalen
=
xcb_get_image_data_length
(
img
);
block
=
block_heap_Alloc
(
img
,
data
+
datalen
-
(
uint8_t
*
)
img
);
if
(
block
==
NULL
)
return
;
block
->
p_buffer
=
data
;
block
->
i_buffer
=
datalen
;
}
/* Send block - zero copy */
if
(
sys
->
es
!=
NULL
)
...
...
@@ -429,12 +505,12 @@ discard:
}
static
es_out_id_t
*
InitES
(
demux_t
*
demux
,
uint_fast16_t
width
,
uint_fast16_t
height
,
uint_fast8_t
depth
)
uint_fast16_t
height
,
uint_fast8_t
depth
,
uint8_t
*
bpp
)
{
demux_sys_t
*
p_sys
=
demux
->
p_sys
;
const
xcb_setup_t
*
setup
=
xcb_get_setup
(
p_sys
->
conn
);
uint32_t
chroma
=
0
;
uint8_t
bpp
;
for
(
const
xcb_format_t
*
fmt
=
xcb_setup_pixmap_formats
(
setup
),
*
end
=
fmt
+
xcb_setup_pixmap_formats_length
(
setup
);
...
...
@@ -442,7 +518,6 @@ static es_out_id_t *InitES (demux_t *demux, uint_fast16_t width,
{
if
(
fmt
->
depth
!=
depth
)
continue
;
bpp
=
fmt
->
depth
;
switch
(
fmt
->
depth
)
{
case
32
:
...
...
@@ -451,10 +526,7 @@ static es_out_id_t *InitES (demux_t *demux, uint_fast16_t width,
break
;
case
24
:
if
(
fmt
->
bits_per_pixel
==
32
)
{
chroma
=
VLC_CODEC_RGB32
;
bpp
=
32
;
}
else
if
(
fmt
->
bits_per_pixel
==
24
)
chroma
=
VLC_CODEC_RGB24
;
break
;
...
...
@@ -472,7 +544,10 @@ static es_out_id_t *InitES (demux_t *demux, uint_fast16_t width,
break
;
}
if
(
chroma
!=
0
)
{
*
bpp
=
fmt
->
bits_per_pixel
;
break
;
}
}
if
(
!
chroma
)
...
...
@@ -485,7 +560,7 @@ static es_out_id_t *InitES (demux_t *demux, uint_fast16_t width,
es_format_Init
(
&
fmt
,
VIDEO_ES
,
chroma
);
fmt
.
video
.
i_chroma
=
chroma
;
fmt
.
video
.
i_bits_per_pixel
=
bpp
;
fmt
.
video
.
i_bits_per_pixel
=
*
bpp
;
fmt
.
video
.
i_sar_num
=
fmt
.
video
.
i_sar_den
=
1
;
fmt
.
video
.
i_frame_rate
=
1000
*
p_sys
->
rate
;
fmt
.
video
.
i_frame_rate_base
=
1000
;
...
...
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