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
4ad88f8a
Commit
4ad88f8a
authored
Aug 31, 2009
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converted fb to "vout display" API.
parent
acd098ab
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
405 additions
and
658 deletions
+405
-658
modules/video_output/fb.c
modules/video_output/fb.c
+405
-658
No files found.
modules/video_output/fb.c
View file @
4ad88f8a
...
...
@@ -45,8 +45,8 @@
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_vout.h>
#include <vlc_
interface
.h>
#include <vlc_vout
_display
.h>
#include <vlc_
picture_pool
.h>
/*****************************************************************************
* Module descriptor
...
...
@@ -54,81 +54,69 @@
#define FB_DEV_VAR "fbdev"
#define DEVICE_TEXT N_("Framebuffer device")
#define DEVICE_LONGTEXT N_(
\
#define DEVICE_LONGTEXT N_(\
"Framebuffer device to use for rendering (usually /dev/fb0).")
#define TTY_TEXT N_("Run fb on current tty.")
#define TTY_LONGTEXT N_(
\
#define TTY_LONGTEXT N_(\
"Run framebuffer on current TTY device (default enabled). " \
"(disable tty handling with caution)"
)
"(disable tty handling with caution)")
#define FB_MODE_TEXT N_("Framebuffer resolution to use.")
#define FB_MODE_LONGTEXT N_(
\
#define FB_MODE_LONGTEXT N_(\
"Select the resolution for the framebuffer. Currently it supports " \
"the values 0=QCIF 1=CIF 2=NTSC 3=PAL, 4=auto (default 4=auto)"
)
"the values 0=QCIF 1=CIF 2=NTSC 3=PAL, 4=auto (default 4=auto)")
#define HW_ACCEL_TEXT N_("Framebuffer uses hw acceleration.")
#define HW_ACCEL_LONGTEXT N_(
\
#define HW_ACCEL_LONGTEXT N_(\
"If your framebuffer supports hardware acceleration or does double buffering " \
"in hardware then you must disable this option. It then does double buffering " \
"in software."
)
"in software.")
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
static
int
Open
(
vlc_object_t
*
);
static
void
Close
(
vlc_object_t
*
);
vlc_module_begin
()
set_shortname
(
"Framebuffer"
)
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VOUT
)
add_file
(
FB_DEV_VAR
,
"/dev/fb0"
,
NULL
,
DEVICE_TEXT
,
DEVICE_LONGTEXT
,
false
)
add_bool
(
"fb-tty"
,
1
,
NULL
,
TTY_TEXT
,
TTY_LONGTEXT
,
true
)
add_obsolete_string
(
"fb-chroma"
);
add_obsolete_string
(
"fb-aspect-ratio"
);
add_integer
(
"fb-mode"
,
4
,
NULL
,
FB_MODE_TEXT
,
FB_MODE_LONGTEXT
,
true
)
add_bool
(
"fb-hw-accel"
,
true
,
NULL
,
HW_ACCEL_TEXT
,
HW_ACCEL_LONGTEXT
,
true
)
set_description
(
N_
(
"GNU/Linux framebuffer video output"
)
)
set_capability
(
"video output"
,
30
)
set_callbacks
(
Open
,
Close
)
set_shortname
(
"Framebuffer"
)
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VOUT
)
add_file
(
FB_DEV_VAR
,
"/dev/fb0"
,
NULL
,
DEVICE_TEXT
,
DEVICE_LONGTEXT
,
false
)
add_bool
(
"fb-tty"
,
1
,
NULL
,
TTY_TEXT
,
TTY_LONGTEXT
,
true
)
add_obsolete_string
(
"fb-chroma"
)
add_obsolete_string
(
"fb-aspect-ratio"
)
add_integer
(
"fb-mode"
,
4
,
NULL
,
FB_MODE_TEXT
,
FB_MODE_LONGTEXT
,
true
)
add_bool
(
"fb-hw-accel"
,
true
,
NULL
,
HW_ACCEL_TEXT
,
HW_ACCEL_LONGTEXT
,
true
)
set_description
(
N_
(
"GNU/Linux framebuffer video output"
)
)
set_capability
(
"vout display"
,
30
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
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
int
Control
(
vout_thread_t
*
,
int
,
va_list
);
static
int
NewPicture
(
vout_thread_t
*
,
picture_t
*
);
static
void
FreePicture
(
vout_thread_t
*
,
picture_t
*
);
static
int
OpenDisplay
(
vout_thread_t
*
);
static
void
CloseDisplay
(
vout_thread_t
*
);
static
void
SwitchDisplay
(
int
i_signal
);
static
void
TextMode
(
int
i_tty
);
static
void
GfxMode
(
int
i_tty
);
static
int
TtyInit
(
vout_thread_t
*
);
static
void
TtyExit
(
vout_thread_t
*
);
#define MAX_DIRECTBUFFERS 1
/*****************************************************************************
* vout_sys_t: video output framebuffer method descriptor
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the FB specific properties of an output thread.
*****************************************************************************/
struct
vout_sys_t
{
static
picture_t
*
Get
(
vout_display_t
*
);
static
void
Display
(
vout_display_t
*
,
picture_t
*
);
static
int
Control
(
vout_display_t
*
,
int
,
va_list
);
static
void
Manage
(
vout_display_t
*
);
/* */
static
int
OpenDisplay
(
vout_display_t
*
,
bool
force_resolution
);
static
void
CloseDisplay
(
vout_display_t
*
);
static
void
SwitchDisplay
(
int
i_signal
);
static
void
TextMode
(
int
tty
);
static
void
GfxMode
(
int
tty
);
static
int
TtyInit
(
vout_display_t
*
);
static
void
TtyExit
(
vout_display_t
*
);
/* */
struct
vout_display_sys_t
{
/* System information */
int
i_
tty
;
/* tty device handle */
bool
b
_tty
;
int
tty
;
/* tty device handle */
bool
is
_tty
;
struct
termios
old_termios
;
/* Original configuration information */
...
...
@@ -137,785 +125,546 @@ struct vout_sys_t
struct
vt_mode
vt_mode
;
/* previous VT mode */
/* Framebuffer information */
int
i_
fd
;
/* device handle */
int
fd
;
/* device handle */
struct
fb_var_screeninfo
old_info
;
/* original mode information */
struct
fb_var_screeninfo
var_info
;
/* current mode information */
bool
b_pan
;
/* does device supports panning ? */
bool
has_pan
;
/* does device supports panning ? */
struct
fb_cmap
fb_cmap
;
/* original colormap */
uint16_t
*
p
_palette
;
/* original palette */
bool
b_hw_accel
;
/* has hardware support */
uint16_t
*
p
alette
;
/* original palette */
bool
is_hw_accel
;
/* has hardware support */
/* Video information */
uint32_t
i_width
;
uint32_t
i_height
;
int
i_bytes_per_pixel
;
bool
b_auto
;
/* Automatically adjust video size to fb size */
uint32_t
width
;
uint32_t
height
;
int
bytes_per_pixel
;
/* Video memory */
uint8_t
*
p_video
;
/* base adress */
size_t
i_page_size
;
/* page size */
};
uint8_t
*
video_ptr
;
/* base adress */
size_t
video_size
;
/* page size */
struct
picture_sys_t
{
uint8_t
*
p_data
;
/* base adress */
picture_t
*
picture
;
picture_pool_t
*
pool
;
};
/**
* This function allocates and initializes a FB vout method.
*/
static
int
Open
(
vlc_object_t
*
p_this
)
static
int
Open
(
vlc_object_t
*
object
)
{
vout_
thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
vout_
sys_t
*
p_
sys
;
vout_
display_t
*
vd
=
(
vout_display_t
*
)
object
;
vout_
display_sys_t
*
sys
;
/* Allocate instance and initialize some members */
p_vout
->
p_sys
=
p_sys
=
calloc
(
1
,
sizeof
(
*
p_sys
)
);
if
(
!
p_sys
)
vd
->
sys
=
sys
=
calloc
(
1
,
sizeof
(
*
sys
)
);
if
(
!
sys
)
return
VLC_ENOMEM
;
p_sys
->
p_video
=
MAP_FAILED
;
/* Does the framebuffer uses hw acceleration? */
p_sys
->
b_hw_accel
=
var_CreateGetBool
(
p_vout
,
"fb-hw-accel"
);
sys
->
is_hw_accel
=
var_CreateGetBool
(
vd
,
"fb-hw-accel"
);
/* Set tty and fb devices */
p_sys
->
i_tty
=
0
;
/* 0 == /dev/tty0 == current console */
p_sys
->
b_tty
=
var_CreateGetBool
(
p_vout
,
"fb-tty"
);
#ifndef WIN32
#if defined(HAVE_ISATTY)
sys
->
tty
=
0
;
/* 0 == /dev/tty0 == current console */
sys
->
is_tty
=
var_CreateGetBool
(
vd
,
"fb-tty"
);
#if !defined(WIN32) && defined(HAVE_ISATTY)
/* Check that stdin is a TTY */
if
(
p_sys
->
b_tty
&&
!
isatty
(
0
)
)
{
msg_Warn
(
p_vout
,
"fd 0 is not a TTY"
);
free
(
p_sys
);
if
(
sys
->
is_tty
&&
!
isatty
(
0
))
{
msg_Warn
(
vd
,
"fd 0 is not a TTY"
);
free
(
sys
);
return
VLC_EGENERIC
;
}
else
{
msg_Warn
(
p_vout
,
"disabling tty handling, use with caution because "
"there is no way to return to the tty."
);
}
#endif
msg_Warn
(
vd
,
"disabling tty handling, use with caution because "
"there is no way to return to the tty."
);
#endif
p_sys
->
b_auto
=
false
;
const
int
i_mode
=
var_CreateGetInteger
(
p_vout
,
"fb-mode"
);
switch
(
i_mode
)
{
const
int
mode
=
var_CreateGetInteger
(
vd
,
"fb-mode"
);
bool
force_resolution
=
true
;
switch
(
mode
)
{
case
0
:
/* QCIF */
p_sys
->
i_
width
=
176
;
p_sys
->
i_
height
=
144
;
sys
->
width
=
176
;
sys
->
height
=
144
;
break
;
case
1
:
/* CIF */
p_sys
->
i_
width
=
352
;
p_sys
->
i_
height
=
288
;
sys
->
width
=
352
;
sys
->
height
=
288
;
break
;
case
2
:
/* NTSC */
p_sys
->
i_
width
=
640
;
p_sys
->
i_
height
=
480
;
sys
->
width
=
640
;
sys
->
height
=
480
;
break
;
case
3
:
/* PAL */
p_sys
->
i_
width
=
704
;
p_sys
->
i_
height
=
576
;
sys
->
width
=
704
;
sys
->
height
=
576
;
break
;
case
4
:
default:
p_sys
->
b_auto
=
tru
e
;
force_resolution
=
fals
e
;
break
;
}
/* tty handling */
if
(
p_sys
->
b_tty
&&
TtyInit
(
p_vout
)
)
{
free
(
p_sys
);
if
(
sys
->
is_tty
&&
TtyInit
(
vd
))
{
free
(
sys
);
return
VLC_EGENERIC
;
}
if
(
OpenDisplay
(
p_vout
)
)
{
Close
(
VLC_OBJECT
(
p_vout
)
);
/* */
sys
->
video_ptr
=
MAP_FAILED
;
sys
->
picture
=
NULL
;
sys
->
pool
=
NULL
;
if
(
OpenDisplay
(
vd
,
force_resolution
))
{
Close
(
VLC_OBJECT
(
vd
));
return
VLC_EGENERIC
;
}
/* */
video_format_t
fmt
=
vd
->
fmt
;
msg_Err
(
vd
,
"var_info.bits_per_pixel = %d"
,
sys
->
var_info
.
bits_per_pixel
);
switch
(
sys
->
var_info
.
bits_per_pixel
)
{
case
8
:
/* FIXME: set the palette */
fmt
.
i_chroma
=
VLC_CODEC_RGB8
;
break
;
case
15
:
fmt
.
i_chroma
=
VLC_CODEC_RGB15
;
break
;
case
16
:
fmt
.
i_chroma
=
VLC_CODEC_RGB16
;
break
;
case
24
:
fmt
.
i_chroma
=
VLC_CODEC_RGB24
;
break
;
case
32
:
fmt
.
i_chroma
=
VLC_CODEC_RGB32
;
break
;
default:
msg_Err
(
vd
,
"unknown screen depth %i"
,
sys
->
var_info
.
bits_per_pixel
);
Close
(
VLC_OBJECT
(
vd
));
return
VLC_EGENERIC
;
}
if
(
sys
->
var_info
.
bits_per_pixel
!=
8
)
{
fmt
.
i_rmask
=
((
1
<<
sys
->
var_info
.
red
.
length
)
-
1
)
<<
sys
->
var_info
.
red
.
offset
;
fmt
.
i_gmask
=
((
1
<<
sys
->
var_info
.
green
.
length
)
-
1
)
<<
sys
->
var_info
.
green
.
offset
;
fmt
.
i_bmask
=
((
1
<<
sys
->
var_info
.
blue
.
length
)
-
1
)
<<
sys
->
var_info
.
blue
.
offset
;
}
fmt
.
i_width
=
sys
->
width
;
fmt
.
i_height
=
sys
->
height
;
/* */
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_vout
->
pf_control
=
Control
;
vout_display_info_t
info
=
vd
->
info
;
info
.
has_hide_mouse
=
true
;
/* */
vd
->
fmt
=
fmt
;
vd
->
info
=
info
;
vd
->
get
=
Get
;
vd
->
prepare
=
NULL
;
vd
->
display
=
Display
;
vd
->
control
=
Control
;
vd
->
manage
=
Manage
;
/* */
vout_display_SendEventFullscreen
(
vd
,
true
);
vout_display_SendEventDisplaySize
(
vd
,
fmt
.
i_width
,
fmt
.
i_height
);
return
VLC_SUCCESS
;
}
/**
* Terminate an output method created by Open
*/
static
void
Close
(
vlc_object_t
*
p_this
)
static
void
Close
(
vlc_object_t
*
object
)
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
vout_display_t
*
vd
=
(
vout_display_t
*
)
object
;
vout_display_sys_t
*
sys
=
vd
->
sys
;
CloseDisplay
(
p_vout
);
if
(
sys
->
pool
)
picture_pool_Delete
(
sys
->
pool
);
if
(
!
sys
->
is_hw_accel
&&
sys
->
picture
)
picture_Release
(
sys
->
picture
);
if
(
p_vout
->
p_sys
->
b_tty
)
TtyExit
(
p_vout
);
CloseDisplay
(
vd
);
/* Destroy structure */
free
(
p_vout
->
p_sys
);
if
(
sys
->
is_tty
)
TtyExit
(
vd
);
free
(
sys
);
}
static
int
TtyInit
(
vout_thread_t
*
p_vout
)
/* */
static
picture_t
*
Get
(
vout_display_t
*
vd
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
struct
termios
new_termios
;
GfxMode
(
p_sys
->
i_tty
);
/* Set keyboard settings */
if
(
tcgetattr
(
0
,
&
p_sys
->
old_termios
)
==
-
1
)
{
msg_Err
(
p_vout
,
"tcgetattr failed"
);
}
vout_display_sys_t
*
sys
=
vd
->
sys
;
if
(
!
sys
->
pool
)
{
if
(
!
sys
->
picture
)
{
picture_resource_t
rsc
;
memset
(
&
rsc
,
0
,
sizeof
(
rsc
));
rsc
.
p
[
0
].
p_pixels
=
sys
->
video_ptr
;
rsc
.
p
[
0
].
i_lines
=
sys
->
var_info
.
yres
;
if
(
sys
->
var_info
.
xres_virtual
)
rsc
.
p
[
0
].
i_pitch
=
sys
->
var_info
.
xres_virtual
*
sys
->
bytes_per_pixel
;
else
rsc
.
p
[
0
].
i_pitch
=
sys
->
var_info
.
xres
*
sys
->
bytes_per_pixel
;
sys
->
picture
=
picture_NewFromResource
(
&
vd
->
fmt
,
&
rsc
);
if
(
!
sys
->
picture
)
return
NULL
;
}
if
(
tcgetattr
(
0
,
&
new_termios
)
==
-
1
)
{
msg_Err
(
p_vout
,
"tcgetattr failed"
);
if
(
sys
->
is_hw_accel
)
sys
->
pool
=
picture_pool_New
(
1
,
&
sys
->
picture
);
else
sys
->
pool
=
picture_pool_NewFromFormat
(
&
vd
->
fmt
,
1
);
if
(
!
sys
->
pool
)
return
NULL
;
}
return
picture_pool_Get
(
sys
->
pool
);
}
static
void
Display
(
vout_display_t
*
vd
,
picture_t
*
picture
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
/* new_termios.c_lflag &= ~ (ICANON | ISIG);
new_termios.c_lflag |= (ECHO | ECHOCTL); */
new_termios
.
c_lflag
&=
~
(
ICANON
);
new_termios
.
c_lflag
&=
~
(
ECHO
|
ECHOCTL
);
new_termios
.
c_iflag
=
0
;
new_termios
.
c_cc
[
VMIN
]
=
1
;
new_termios
.
c_cc
[
VTIME
]
=
0
;
if
(
tcsetattr
(
0
,
TCSAFLUSH
,
&
new_termios
)
==
-
1
)
{
msg_Err
(
p_vout
,
"tcsetattr failed"
);
}
/* swap the two Y offsets if the drivers supports panning */
if
(
sys
->
has_pan
)
{
sys
->
var_info
.
yoffset
=
0
;
/*vd->sys->var_info.yoffset = vd->sys->var_info.yres; */
ioctl
(
p_sys
->
i_tty
,
VT_RELDISP
,
VT_ACKACQ
);
/* the X offset should be 0, but who knows ...
* some other app might have played with the framebuffer */
sys
->
var_info
.
xoffset
=
0
;
/* Set-up tty signal handler to be aware of tty changes */
struct
sigaction
sig_tty
;
memset
(
&
sig_tty
,
0
,
sizeof
(
sig_tty
)
);
sig_tty
.
sa_handler
=
SwitchDisplay
;
sigemptyset
(
&
sig_tty
.
sa_mask
);
if
(
sigaction
(
SIGUSR1
,
&
sig_tty
,
&
p_sys
->
sig_usr1
)
||
sigaction
(
SIGUSR2
,
&
sig_tty
,
&
p_sys
->
sig_usr2
)
)
{
msg_Err
(
p_vout
,
"cannot set signal handler (%m)"
);
tcsetattr
(
0
,
0
,
&
p_sys
->
old_termios
);
TextMode
(
p_sys
->
i_tty
);
return
VLC_EGENERIC
;
/* FIXME 'static' is damn wrong and it's dead code ... */
static
int
panned
=
0
;
if
(
panned
<
0
)
{
ioctl
(
sys
->
fd
,
FBIOPAN_DISPLAY
,
&
sys
->
var_info
);
panned
++
;
}
}
/* Set-up tty according to new signal handler */
if
(
-
1
==
ioctl
(
p_sys
->
i_tty
,
VT_GETMODE
,
&
p_sys
->
vt_mode
)
)
{
msg_Err
(
p_vout
,
"cannot get terminal mode (%m)"
);
sigaction
(
SIGUSR1
,
&
p_sys
->
sig_usr1
,
NULL
);
sigaction
(
SIGUSR2
,
&
p_sys
->
sig_usr2
,
NULL
);
tcsetattr
(
0
,
0
,
&
p_sys
->
old_termios
);
TextMode
(
p_sys
->
i_tty
);
return
VLC_EGENERIC
;
}
struct
vt_mode
vt_mode
=
p_sys
->
vt_mode
;
vt_mode
.
mode
=
VT_PROCESS
;
vt_mode
.
waitv
=
0
;
vt_mode
.
relsig
=
SIGUSR1
;
vt_mode
.
acqsig
=
SIGUSR2
;
if
(
!
sys
->
is_hw_accel
)
picture_Copy
(
sys
->
picture
,
picture
);
if
(
-
1
==
ioctl
(
p_sys
->
i_tty
,
VT_SETMODE
,
&
vt_mode
)
)
{
msg_Err
(
p_vout
,
"cannot set terminal mode (%m)"
);
sigaction
(
SIGUSR1
,
&
p_sys
->
sig_usr1
,
NULL
);
sigaction
(
SIGUSR2
,
&
p_sys
->
sig_usr2
,
NULL
);
tcsetattr
(
0
,
0
,
&
p_sys
->
old_termios
);
TextMode
(
p_sys
->
i_tty
);
return
VLC_EGENERIC
;
}
return
VLC_SUCCESS
;
picture_Release
(
picture
);
}
static
void
TtyExit
(
vout_thread_t
*
p_vout
)
static
int
Control
(
vout_display_t
*
vd
,
int
i_query
,
va_list
args
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
/* Reset the terminal */
ioctl
(
p_sys
->
i_tty
,
VT_SETMODE
,
&
p_sys
->
vt_mode
);
/* Remove signal handlers */
sigaction
(
SIGUSR1
,
&
p_sys
->
sig_usr1
,
NULL
);
sigaction
(
SIGUSR2
,
&
p_sys
->
sig_usr2
,
NULL
);
vout_display_sys_t
*
sys
=
vd
->
sys
;
/* Reset the keyboard state */
tcsetattr
(
0
,
0
,
&
p_sys
->
old_termios
);
/* Return to text mode */
TextMode
(
p_sys
->
i_tty
);
}
/*****************************************************************************
* NewPicture: allocate a picture
*****************************************************************************
* Returns 0 on success, -1 otherwise
*****************************************************************************/
static
int
NewPicture
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
/* We know the chroma, allocate a buffer which will be used
* directly by the decoder */
p_pic
->
p_sys
=
malloc
(
sizeof
(
picture_sys_t
)
);
if
(
p_pic
->
p_sys
==
NULL
)
{
return
VLC_ENOMEM
;
switch
(
i_query
)
{
case
VOUT_DISPLAY_CHANGE_DISPLAY_SIZE
:
{
const
vout_display_cfg_t
*
cfg
=
va_arg
(
args
,
const
vout_display_cfg_t
*
);
if
(
cfg
->
display
.
width
!=
sys
->
width
||
cfg
->
display
.
height
!=
sys
->
height
)
return
VLC_EGENERIC
;
return
VLC_SUCCESS
;
}
/* Fill in picture_t fields */
if
(
picture_Setup
(
p_pic
,
p_vout
->
output
.
i_chroma
,
p_vout
->
output
.
i_width
,
p_vout
->
output
.
i_height
,
p_vout
->
output
.
i_aspect
)
)
{
free
(
p_pic
);
default:
msg_Err
(
vd
,
"Unsupported query in vout display fb"
);
return
VLC_EGENERIC
;
}
p_pic
->
p_sys
->
p_data
=
malloc
(
p_vout
->
p_sys
->
i_page_size
);
if
(
!
p_pic
->
p_sys
->
p_data
)
}
static
void
Manage
(
vout_display_t
*
vd
)
{
VLC_UNUSED
(
vd
);
#if 0
/*
* Size change
*/
if (vd->i_changes & VOUT_SIZE_CHANGE)
{
free
(
p_pic
->
p_sys
);
p_pic
->
p_sys
=
NULL
;
return
VLC_ENOMEM
;
}
msg_Dbg(vd, "reinitializing framebuffer screen");
vd->i_changes &= ~VOUT_SIZE_CHANGE;
p_pic
->
p
->
p_pixels
=
(
uint8_t
*
)
p_pic
->
p_sys
->
p_data
;
vout_display_SendEventDisplaySize()
;
p_pic
->
p
->
i_pixel_pitch
=
p_vout
->
p_sys
->
i_bytes_per_pixel
;
p_pic
->
p
->
i_lines
=
p_vout
->
p_sys
->
var_info
.
yres
;
p_pic
->
p
->
i_visible_lines
=
p_vout
->
p_sys
->
var_info
.
yres
;
/* Clear screen */
memset(vd->sys->video_ptr, 0, vd->sys->video_size);
if
(
p_vout
->
p_sys
->
var_info
.
xres_virtual
)
{
p_pic
->
p
->
i_pitch
=
p_vout
->
p_sys
->
var_info
.
xres_virtual
*
p_vout
->
p_sys
->
i_bytes_per_pixel
;
}
else
{
p_pic
->
p
->
i_pitch
=
p_vout
->
p_sys
->
var_info
.
xres
*
p_vout
->
p_sys
->
i_bytes_per_pixel
;
}
p_pic
->
p
->
i_visible_pitch
=
p_vout
->
p_sys
->
var_info
.
xres
*
p_vout
->
p_sys
->
i_bytes_per_pixel
;
p_pic
->
i_planes
=
1
;
return
VLC_SUCCESS
;
}
/*****************************************************************************
* FreePicture: destroy a picture allocated with NewPicture
*****************************************************************************
* Destroy Image AND associated data.
*****************************************************************************/
static
void
FreePicture
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
{
VLC_UNUSED
(
p_vout
);
free
(
p_pic
->
p_sys
->
p_data
);
free
(
p_pic
->
p_sys
);
p_pic
->
p_sys
=
NULL
;
#endif
}
/*****************************************************************************
* Init: initialize framebuffer video thread output method
*****************************************************************************/
static
int
Init
(
vout_thread_t
*
p_vout
)
/* following functions are local */
static
int
TtyInit
(
vout_display_t
*
vd
)
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
int
i_index
;
picture_t
*
p_pic
=
NULL
;
I_OUTPUTPICTURES
=
0
;
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
;
vout_display_sys_t
*
sys
=
vd
->
sys
;
p_vout
->
fmt_out
=
p_vout
->
fmt_in
;
struct
termios
new_termios
;
/* Initialize the output structure: RGB with square pixels, whatever
* the input format is, since it's the only format we know */
switch
(
p_sys
->
var_info
.
bits_per_pixel
)
{
case
8
:
/* FIXME: set the palette */
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB8
;
break
;
case
15
:
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB15
;
break
;
case
16
:
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB16
;
break
;
case
24
:
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB24
;
break
;
case
32
:
p_vout
->
output
.
i_chroma
=
VLC_CODEC_RGB32
;
break
;
default:
msg_Err
(
p_vout
,
"unknown screen depth %i"
,
p_vout
->
p_sys
->
var_info
.
bits_per_pixel
);
return
VLC_EGENERIC
;
}
GfxMode
(
sys
->
tty
);
if
(
p_sys
->
var_info
.
bits_per_pixel
!=
8
)
{
p_vout
->
output
.
i_rmask
=
(
(
1
<<
p_sys
->
var_info
.
red
.
length
)
-
1
)
<<
p_sys
->
var_info
.
red
.
offset
;
p_vout
->
output
.
i_gmask
=
(
(
1
<<
p_sys
->
var_info
.
green
.
length
)
-
1
)
<<
p_sys
->
var_info
.
green
.
offset
;
p_vout
->
output
.
i_bmask
=
(
(
1
<<
p_sys
->
var_info
.
blue
.
length
)
-
1
)
<<
p_sys
->
var_info
.
blue
.
offset
;
/* Set keyboard settings */
if
(
tcgetattr
(
0
,
&
sys
->
old_termios
)
==
-
1
)
{
msg_Err
(
vd
,
"tcgetattr failed"
);
}
p_vout
->
fmt_out
.
i_chroma
=
p_vout
->
output
.
i_chroma
;
p_vout
->
output
.
i_width
=
p_vout
->
fmt_out
.
i_width
=
p_vout
->
fmt_out
.
i_visible_width
=
p_sys
->
i_width
;
p_vout
->
output
.
i_height
=
p_vout
->
fmt_out
.
i_height
=
p_vout
->
fmt_out
.
i_visible_height
=
p_sys
->
i_height
;
/* Assume we have square pixels */
p_vout
->
output
.
i_aspect
=
(
p_sys
->
i_width
*
VOUT_ASPECT_FACTOR
)
/
p_sys
->
i_height
;
p_vout
->
fmt_out
.
i_sar_num
=
p_vout
->
fmt_out
.
i_sar_den
=
1
;
p_vout
->
fmt_out
.
i_aspect
=
p_vout
->
render
.
i_aspect
=
p_vout
->
output
.
i_aspect
;
p_vout
->
fmt_out
.
i_x_offset
=
p_vout
->
fmt_out
.
i_y_offset
=
0
;
/* Clear the screen */
memset
(
p_sys
->
p_video
,
0
,
p_sys
->
i_page_size
);
if
(
!
p_sys
->
b_hw_accel
)
{
/* Try to initialize up to MAX_DIRECTBUFFERS direct buffers */
while
(
I_OUTPUTPICTURES
<
MAX_DIRECTBUFFERS
)
{
p_pic
=
NULL
;
/* Find an empty picture slot */
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
;
}
}
/* Allocate the picture */
if
(
p_pic
==
NULL
||
NewPicture
(
p_vout
,
p_pic
)
)
{
break
;
}
p_pic
->
i_status
=
DESTROYED_PICTURE
;
p_pic
->
i_type
=
DIRECT_PICTURE
;
PP_OUTPUTPICTURE
[
I_OUTPUTPICTURES
]
=
p_pic
;
I_OUTPUTPICTURES
++
;
}
if
(
tcgetattr
(
0
,
&
new_termios
)
==
-
1
)
{
msg_Err
(
vd
,
"tcgetattr failed"
);
}
else
{
/* Try to initialize 1 direct buffer */
p_pic
=
NULL
;
/* Find an empty picture slot */
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
;
}
}
/* Allocate the picture */
if
(
p_pic
==
NULL
)
{
return
VLC_EGENERIC
;
}
/* We know the chroma, allocate a buffer which will be used
* directly by the decoder */
p_pic
->
p
->
p_pixels
=
p_vout
->
p_sys
->
p_video
;
p_pic
->
p
->
i_pixel_pitch
=
p_vout
->
p_sys
->
i_bytes_per_pixel
;
p_pic
->
p
->
i_lines
=
p_vout
->
p_sys
->
var_info
.
yres
;
p_pic
->
p
->
i_visible_lines
=
p_vout
->
p_sys
->
var_info
.
yres
;
if
(
p_vout
->
p_sys
->
var_info
.
xres_virtual
)
{
p_pic
->
p
->
i_pitch
=
p_vout
->
p_sys
->
var_info
.
xres_virtual
*
p_vout
->
p_sys
->
i_bytes_per_pixel
;
}
else
{
p_pic
->
p
->
i_pitch
=
p_vout
->
p_sys
->
var_info
.
xres
*
p_vout
->
p_sys
->
i_bytes_per_pixel
;
}
p_pic
->
p
->
i_visible_pitch
=
p_vout
->
p_sys
->
var_info
.
xres
*
p_vout
->
p_sys
->
i_bytes_per_pixel
;
p_pic
->
i_planes
=
1
;
p_pic
->
i_status
=
DESTROYED_PICTURE
;
p_pic
->
i_type
=
DIRECT_PICTURE
;
PP_OUTPUTPICTURE
[
I_OUTPUTPICTURES
]
=
p_pic
;
/* new_termios.c_lflag &= ~ (ICANON | ISIG);
new_termios.c_lflag |= (ECHO | ECHOCTL); */
new_termios
.
c_lflag
&=
~
(
ICANON
);
new_termios
.
c_lflag
&=
~
(
ECHO
|
ECHOCTL
);
new_termios
.
c_iflag
=
0
;
new_termios
.
c_cc
[
VMIN
]
=
1
;
new_termios
.
c_cc
[
VTIME
]
=
0
;
I_OUTPUTPICTURES
++
;
if
(
tcsetattr
(
0
,
TCSAFLUSH
,
&
new_termios
)
==
-
1
)
{
msg_Err
(
vd
,
"tcsetattr failed"
);
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* End: terminate framebuffer video thread output method
*****************************************************************************/
static
void
End
(
vout_thread_t
*
p_vout
)
{
if
(
!
p_vout
->
p_sys
->
b_hw_accel
)
{
int
i_index
;
/* Free the direct buffers we allocated */
for
(
i_index
=
I_OUTPUTPICTURES
;
i_index
;
)
{
i_index
--
;
FreePicture
(
p_vout
,
PP_OUTPUTPICTURE
[
i_index
]
);
}
ioctl
(
sys
->
tty
,
VT_RELDISP
,
VT_ACKACQ
);
/* Set-up tty signal handler to be aware of tty changes */
struct
sigaction
sig_tty
;
memset
(
&
sig_tty
,
0
,
sizeof
(
sig_tty
));
sig_tty
.
sa_handler
=
SwitchDisplay
;
sigemptyset
(
&
sig_tty
.
sa_mask
);
if
(
sigaction
(
SIGUSR1
,
&
sig_tty
,
&
sys
->
sig_usr1
)
||
sigaction
(
SIGUSR2
,
&
sig_tty
,
&
sys
->
sig_usr2
))
{
msg_Err
(
vd
,
"cannot set signal handler (%m)"
);
/* FIXME SIGUSR1 could have succeed */
goto
error_signal
;
}
/* Clear the screen */
memset
(
p_vout
->
p_sys
->
p_video
,
0
,
p_vout
->
p_sys
->
i_page_size
);
}
/*****************************************************************************
* Control: control facility for the vout
*****************************************************************************/
static
int
Control
(
vout_thread_t
*
p_vout
,
int
i_query
,
va_list
args
)
{
(
void
)
p_vout
;
(
void
)
i_query
;
(
void
)
args
;
return
VLC_EGENERIC
;
}
/*****************************************************************************
* Manage: handle FB events
*****************************************************************************
* This function should be called regularly by video output thread. It manages
* console events. It returns a non null value on error.
*****************************************************************************/
static
int
Manage
(
vout_thread_t
*
p_vout
)
{
#if 0
uint8_t buf;
if ( read(0, &buf, 1) == 1)
{
switch( buf )
{
case 'q':
libvlc_Quit( p_vout->p_libvlc );
break;
default:
break;
}
/* Set-up tty according to new signal handler */
if
(
-
1
==
ioctl
(
sys
->
tty
,
VT_GETMODE
,
&
sys
->
vt_mode
))
{
msg_Err
(
vd
,
"cannot get terminal mode (%m)"
);
goto
error
;
}
#endif
/*
* Size change
*/
if
(
p_vout
->
i_changes
&
VOUT_SIZE_CHANGE
)
{
msg_Dbg
(
p_vout
,
"reinitializing framebuffer screen"
);
p_vout
->
i_changes
&=
~
VOUT_SIZE_CHANGE
;
/* Destroy XImages to change their size */
End
(
p_vout
);
/* Recreate XImages. If SysInit failed, the thread can't go on. */
if
(
Init
(
p_vout
)
)
{
msg_Err
(
p_vout
,
"cannot reinit framebuffer screen"
);
return
VLC_EGENERIC
;
}
/* Clear screen */
memset
(
p_vout
->
p_sys
->
p_video
,
0
,
p_vout
->
p_sys
->
i_page_size
);
struct
vt_mode
vt_mode
=
sys
->
vt_mode
;
vt_mode
.
mode
=
VT_PROCESS
;
vt_mode
.
waitv
=
0
;
vt_mode
.
relsig
=
SIGUSR1
;
vt_mode
.
acqsig
=
SIGUSR2
;
#if 0
/* Tell the video output thread that it will need to rebuild YUV
* tables. This is needed since conversion buffer size may have changed */
p_vout->i_changes |= VOUT_YUV_CHANGE;
#endif
if
(
-
1
==
ioctl
(
sys
->
tty
,
VT_SETMODE
,
&
vt_mode
))
{
msg_Err
(
vd
,
"cannot set terminal mode (%m)"
);
goto
error
;
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Display: displays previously rendered output
*****************************************************************************
* This function send the currently rendered image to FB image, waits until
* it is displayed and switch the two rendering buffers, preparing next frame.
*****************************************************************************/
static
void
Display
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
error:
sigaction
(
SIGUSR1
,
&
sys
->
sig_usr1
,
NULL
);
sigaction
(
SIGUSR2
,
&
sys
->
sig_usr2
,
NULL
);
error_signal:
tcsetattr
(
0
,
0
,
&
sys
->
old_termios
);
TextMode
(
sys
->
tty
);
return
VLC_EGENERIC
;
}
static
void
TtyExit
(
vout_display_t
*
vd
)
{
static
int
panned
=
0
;
/* swap the two Y offsets if the drivers supports panning */
if
(
p_vout
->
p_sys
->
b_pan
)
{
p_vout
->
p_sys
->
var_info
.
yoffset
=
0
;
/*p_vout->p_sys->var_info.yoffset = p_vout->p_sys->var_info.yres; */
vout_display_sys_t
*
sys
=
vd
->
sys
;
/* the X offset should be 0, but who knows ...
* some other app might have played with the framebuffer */
p_vout
->
p_sys
->
var_info
.
xoffset
=
0
;
if
(
panned
<
0
)
{
ioctl
(
p_vout
->
p_sys
->
i_fd
,
FBIOPAN_DISPLAY
,
&
p_vout
->
p_sys
->
var_info
);
panned
++
;
}
}
/* Reset the terminal */
ioctl
(
sys
->
tty
,
VT_SETMODE
,
&
sys
->
vt_mode
);
if
(
!
p_vout
->
p_sys
->
b_hw_accel
)
{
vlc_memcpy
(
p_vout
->
p_sys
->
p_video
,
p_pic
->
p
->
p_pixels
,
p_vout
->
p_sys
->
i_page_size
);
}
}
/* Remove signal handlers */
sigaction
(
SIGUSR1
,
&
sys
->
sig_usr1
,
NULL
);
sigaction
(
SIGUSR2
,
&
sys
->
sig_usr2
,
NULL
);
#if 0
static void SetPalette( vout_thread_t *p_vout, uint16_t *red, uint16_t *green,
uint16_t *blue, uint16_t *transp )
{
struct fb_cmap cmap = { 0, 256, red, green, blue, transp };
/* Reset the keyboard state */
tcsetattr
(
0
,
0
,
&
sys
->
old_termios
);
ioctl( p_vout->p_sys->i_fd, FBIOPUTCMAP, &cmap );
/* Return to text mode */
TextMode
(
sys
->
tty
);
}
#endif
/* following functions are local */
/*****************************************************************************
* OpenDisplay: initialize framebuffer
*****************************************************************************/
static
int
OpenDisplay
(
vout_thread_t
*
p_vout
)
static
int
OpenDisplay
(
vout_display_t
*
vd
,
bool
force_resolution
)
{
vout_
sys_t
*
p_sys
=
(
vout_sys_t
*
)
p_vout
->
p_
sys
;
vout_
display_sys_t
*
sys
=
vd
->
sys
;
char
*
psz_device
;
/* framebuffer device path */
struct
fb_fix_screeninfo
fix_info
;
/* framebuffer fix information */
/* Open framebuffer device */
if
(
!
(
psz_device
=
config_GetPsz
(
p_vout
,
FB_DEV_VAR
))
)
{
msg_Err
(
p_vout
,
"don't know which fb device to open"
);
if
(
!
(
psz_device
=
config_GetPsz
(
vd
,
FB_DEV_VAR
)))
{
msg_Err
(
vd
,
"don't know which fb device to open"
);
return
VLC_EGENERIC
;
}
p_sys
->
i_fd
=
open
(
psz_device
,
O_RDWR
);
if
(
p_sys
->
i_fd
==
-
1
)
{
msg_Err
(
p_vout
,
"cannot open %s (%m)"
,
psz_device
);
free
(
psz_device
);
sys
->
fd
=
open
(
psz_device
,
O_RDWR
);
if
(
sys
->
fd
==
-
1
)
{
msg_Err
(
vd
,
"cannot open %s (%m)"
,
psz_device
);
free
(
psz_device
);
return
VLC_EGENERIC
;
}
free
(
psz_device
);
free
(
psz_device
);
/* Get framebuffer device information */
if
(
ioctl
(
p_sys
->
i_fd
,
FBIOGET_VSCREENINFO
,
&
p_sys
->
var_info
)
)
{
msg_Err
(
p_vout
,
"cannot get fb info (%m)"
);
close
(
p_sys
->
i_fd
);
if
(
ioctl
(
sys
->
fd
,
FBIOGET_VSCREENINFO
,
&
sys
->
var_info
))
{
msg_Err
(
vd
,
"cannot get fb info (%m)"
);
close
(
sys
->
fd
);
return
VLC_EGENERIC
;
}
memcpy
(
&
p_sys
->
old_info
,
&
p_sys
->
var_info
,
sizeof
(
struct
fb_var_screeninfo
)
);
sys
->
old_info
=
sys
->
var_info
;
/* Get some info on the framebuffer itself */
if
(
!
p_sys
->
b_auto
)
{
p_sys
->
var_info
.
xres
=
p_sys
->
var_info
.
xres_virtual
=
p_sys
->
i_width
;
p_sys
->
var_info
.
yres
=
p_sys
->
var_info
.
yres_virtual
=
p_sys
->
i_height
;
p_vout
->
fmt_out
.
i_width
=
p_sys
->
i_width
;
p_vout
->
fmt_out
.
i_height
=
p_sys
->
i_height
;
if
(
force_resolution
)
{
sys
->
var_info
.
xres
=
sys
->
var_info
.
xres_virtual
=
sys
->
width
;
sys
->
var_info
.
yres
=
sys
->
var_info
.
yres_virtual
=
sys
->
height
;
}
/* Set some attributes */
p_sys
->
var_info
.
activate
=
p_sys
->
b_tty
?
FB_ACTIVATE_NXTOPEN
:
FB_ACTIVATE_NOW
;
p_sys
->
var_info
.
xoffset
=
0
;
p_sys
->
var_info
.
yoffset
=
0
;
if
(
ioctl
(
p_sys
->
i_fd
,
FBIOPUT_VSCREENINFO
,
&
p_sys
->
var_info
)
)
{
msg_Err
(
p_vout
,
"cannot set fb info (%m)"
);
close
(
p_sys
->
i_fd
);
sys
->
var_info
.
activate
=
sys
->
is_tty
?
FB_ACTIVATE_NXTOPEN
:
FB_ACTIVATE_NOW
;
sys
->
var_info
.
xoffset
=
0
;
sys
->
var_info
.
yoffset
=
0
;
if
(
ioctl
(
sys
->
fd
,
FBIOPUT_VSCREENINFO
,
&
sys
->
var_info
))
{
msg_Err
(
vd
,
"cannot set fb info (%m)"
);
close
(
sys
->
fd
);
return
VLC_EGENERIC
;
}
/* Get some information again, in the definitive configuration */
if
(
ioctl
(
p_sys
->
i_fd
,
FBIOGET_FSCREENINFO
,
&
fix_info
)
||
ioctl
(
p_sys
->
i_fd
,
FBIOGET_VSCREENINFO
,
&
p_sys
->
var_info
)
)
{
msg_Err
(
p_vout
,
"cannot get additional fb info (%m)"
);
if
(
ioctl
(
sys
->
fd
,
FBIOGET_FSCREENINFO
,
&
fix_info
)
||
ioctl
(
sys
->
fd
,
FBIOGET_VSCREENINFO
,
&
sys
->
var_info
))
{
msg_Err
(
vd
,
"cannot get additional fb info (%m)"
);
/* Restore fb config */
ioctl
(
p_sys
->
i_fd
,
FBIOPUT_VSCREENINFO
,
&
p_sys
->
old_info
);
ioctl
(
sys
->
fd
,
FBIOPUT_VSCREENINFO
,
&
sys
->
old_info
);
close
(
p_sys
->
i_fd
);
close
(
sys
->
fd
);
return
VLC_EGENERIC
;
}
/* If the fb has limitations on mode change,
* then keep the resolution of the fb */
if
(
(
p_sys
->
i_height
!=
p_sys
->
var_info
.
yres
)
||
(
p_sys
->
i_width
!=
p_sys
->
var_info
.
xres
)
)
{
p_sys
->
b_auto
=
true
;
msg_Warn
(
p_vout
,
"using framebuffer native resolution instead of requested (%ix%i)"
,
p_sys
->
i_width
,
p_sys
->
i_height
);
if
((
sys
->
height
!=
sys
->
var_info
.
yres
)
||
(
sys
->
width
!=
sys
->
var_info
.
xres
))
{
msg_Warn
(
vd
,
"using framebuffer native resolution instead of requested (%ix%i)"
,
sys
->
width
,
sys
->
height
);
}
p_sys
->
i_height
=
p_sys
->
var_info
.
yres
;
p_sys
->
i_width
=
p_sys
->
var_info
.
xres_virtual
?
p_sys
->
var_info
.
xres_virtual
:
p_sys
->
var_info
.
xres
;
sys
->
height
=
sys
->
var_info
.
yres
;
sys
->
width
=
sys
->
var_info
.
xres_virtual
?
sys
->
var_info
.
xres_virtual
:
sys
->
var_info
.
xres
;
/* FIXME: if the image is full-size, it gets cropped on the left
* because of the xres / xres_virtual slight difference */
msg_Dbg
(
p_vout
,
"%ix%i (virtual %ix%i) (request %ix%i)"
,
p_sys
->
var_info
.
xres
,
p_
sys
->
var_info
.
yres
,
p_
sys
->
var_info
.
xres_virtual
,
p_
sys
->
var_info
.
yres_virtual
,
p_sys
->
i_width
,
p_sys
->
i_height
);
msg_Dbg
(
vd
,
"%ix%i (virtual %ix%i) (request %ix%i)"
,
sys
->
var_info
.
xres
,
sys
->
var_info
.
yres
,
sys
->
var_info
.
xres_virtual
,
sys
->
var_info
.
yres_virtual
,
sys
->
width
,
sys
->
height
);
p_sys
->
p_
palette
=
NULL
;
p_sys
->
b_pan
=
(
fix_info
.
ypanstep
||
fix_info
.
ywrapstep
);
sys
->
palette
=
NULL
;
sys
->
has_pan
=
(
fix_info
.
ypanstep
||
fix_info
.
ywrapstep
);
switch
(
p_sys
->
var_info
.
bits_per_pixel
)
{
switch
(
sys
->
var_info
.
bits_per_pixel
)
{
case
8
:
p_sys
->
p_palette
=
malloc
(
8
*
256
*
sizeof
(
uint16_t
)
);
if
(
!
p_sys
->
p_palette
)
{
sys
->
palette
=
malloc
(
8
*
256
*
sizeof
(
uint16_t
));
if
(
!
sys
->
palette
)
{
/* Restore fb config */
ioctl
(
p_sys
->
i_fd
,
FBIOPUT_VSCREENINFO
,
&
p_sys
->
old_info
);
ioctl
(
sys
->
fd
,
FBIOPUT_VSCREENINFO
,
&
sys
->
old_info
);
close
(
p_sys
->
i_fd
);
close
(
sys
->
fd
);
return
VLC_ENOMEM
;
}
p_
sys
->
fb_cmap
.
start
=
0
;
p_
sys
->
fb_cmap
.
len
=
256
;
p_sys
->
fb_cmap
.
red
=
p_sys
->
p_
palette
;
p_sys
->
fb_cmap
.
green
=
p_sys
->
p_palette
+
256
*
sizeof
(
uint16_t
);
p_sys
->
fb_cmap
.
blue
=
p_sys
->
p_palette
+
2
*
256
*
sizeof
(
uint16_t
);
p_sys
->
fb_cmap
.
transp
=
p_sys
->
p_palette
+
3
*
256
*
sizeof
(
uint16_t
);
sys
->
fb_cmap
.
start
=
0
;
sys
->
fb_cmap
.
len
=
256
;
sys
->
fb_cmap
.
red
=
sys
->
palette
;
sys
->
fb_cmap
.
green
=
sys
->
palette
+
256
*
sizeof
(
uint16_t
);
sys
->
fb_cmap
.
blue
=
sys
->
palette
+
2
*
256
*
sizeof
(
uint16_t
);
sys
->
fb_cmap
.
transp
=
sys
->
palette
+
3
*
256
*
sizeof
(
uint16_t
);
/* Save the colormap */
ioctl
(
p_sys
->
i_fd
,
FBIOGETCMAP
,
&
p_sys
->
fb_cmap
);
ioctl
(
sys
->
fd
,
FBIOGETCMAP
,
&
sys
->
fb_cmap
);
p_sys
->
i_
bytes_per_pixel
=
1
;
sys
->
bytes_per_pixel
=
1
;
break
;
case
15
:
case
16
:
p_sys
->
i_
bytes_per_pixel
=
2
;
sys
->
bytes_per_pixel
=
2
;
break
;
case
24
:
p_sys
->
i_
bytes_per_pixel
=
3
;
sys
->
bytes_per_pixel
=
3
;
break
;
case
32
:
p_sys
->
i_
bytes_per_pixel
=
4
;
sys
->
bytes_per_pixel
=
4
;
break
;
default:
msg_Err
(
p_vout
,
"screen depth %d is not supported"
,
p_sys
->
var_info
.
bits_per_pixel
);
msg_Err
(
vd
,
"screen depth %d is not supported"
,
sys
->
var_info
.
bits_per_pixel
);
/* Restore fb config */
ioctl
(
p_sys
->
i_fd
,
FBIOPUT_VSCREENINFO
,
&
p_sys
->
old_info
);
ioctl
(
sys
->
fd
,
FBIOPUT_VSCREENINFO
,
&
sys
->
old_info
);
close
(
p_sys
->
i_fd
);
close
(
sys
->
fd
);
return
VLC_EGENERIC
;
}
p_sys
->
i_page_size
=
p_sys
->
i_width
*
p_sys
->
i_height
*
p_sys
->
i_bytes_per_pixel
;
sys
->
video_size
=
sys
->
width
*
sys
->
height
*
sys
->
bytes_per_pixel
;
/* Map a framebuffer at the beginning */
p_sys
->
p_video
=
mmap
(
NULL
,
p_sys
->
i_page_size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
p_sys
->
i_fd
,
0
);
sys
->
video_ptr
=
mmap
(
NULL
,
sys
->
video_size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
sys
->
fd
,
0
);
if
(
p_sys
->
p_video
==
MAP_FAILED
)
{
msg_Err
(
p_vout
,
"cannot map video memory (%m)"
);
if
(
sys
->
video_ptr
==
MAP_FAILED
)
{
msg_Err
(
vd
,
"cannot map video memory (%m)"
);
if
(
p_sys
->
var_info
.
bits_per_pixel
==
8
)
{
free
(
p_sys
->
p_palette
);
p_sys
->
p_palette
=
NULL
;
if
(
sys
->
var_info
.
bits_per_pixel
==
8
)
{
free
(
sys
->
palette
);
sys
->
palette
=
NULL
;
}
/* Restore fb config */
ioctl
(
p_sys
->
i_fd
,
FBIOPUT_VSCREENINFO
,
&
p_vout
->
p_sys
->
old_info
);
ioctl
(
sys
->
fd
,
FBIOPUT_VSCREENINFO
,
&
sys
->
old_info
);
close
(
p_sys
->
i_fd
);
close
(
sys
->
fd
);
return
VLC_EGENERIC
;
}
/* Clear the screen */
memset
(
sys
->
video_ptr
,
0
,
sys
->
video_size
);
msg_Dbg
(
p_vout
,
"framebuffer type=%d, visual=%d, ypanstep=%d, "
"ywrap=%d, accel=%d"
,
fix_info
.
type
,
fix_info
.
visual
,
fix_info
.
ypanstep
,
fix_info
.
ywrapstep
,
fix_info
.
accel
);
msg_Dbg
(
vd
,
"framebuffer type=%d, visual=%d, ypanstep=%d, ywrap=%d, accel=%d"
,
fix_info
.
type
,
fix_info
.
visual
,
fix_info
.
ypanstep
,
fix_info
.
ywrapstep
,
fix_info
.
accel
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* CloseDisplay: terminate FB video thread output method
*****************************************************************************/
static
void
CloseDisplay
(
vout_thread_t
*
p_vout
)
static
void
CloseDisplay
(
vout_display_t
*
vd
)
{
if
(
p_vout
->
p_sys
->
p_video
!=
MAP_FAILED
)
{
vout_display_sys_t
*
sys
=
vd
->
sys
;
if
(
sys
->
video_ptr
!=
MAP_FAILED
)
{
/* Clear display */
memset
(
p_vout
->
p_sys
->
p_video
,
0
,
p_vout
->
p_sys
->
i_page_size
);
munmap
(
p_vout
->
p_sys
->
p_video
,
p_vout
->
p_sys
->
i_page_size
);
memset
(
sys
->
video_ptr
,
0
,
sys
->
video_size
);
munmap
(
sys
->
video_ptr
,
sys
->
video_size
);
}
if
(
p_vout
->
p_sys
->
i_fd
>=
0
)
{
if
(
sys
->
fd
>=
0
)
{
/* Restore palette */
if
(
p_vout
->
p_sys
->
var_info
.
bits_per_pixel
==
8
)
{
ioctl
(
p_vout
->
p_sys
->
i_fd
,
FBIOPUTCMAP
,
&
p_vout
->
p_sys
->
fb_cmap
);
free
(
p_vout
->
p_sys
->
p_palette
);
p_vout
->
p_sys
->
p_palette
=
NULL
;
if
(
sys
->
var_info
.
bits_per_pixel
==
8
)
{
ioctl
(
sys
->
fd
,
FBIOPUTCMAP
,
&
sys
->
fb_cmap
);
free
(
sys
->
palette
);
sys
->
palette
=
NULL
;
}
/* Restore fb config */
ioctl
(
p_vout
->
p_sys
->
i_fd
,
FBIOPUT_VSCREENINFO
,
&
p_vout
->
p_sys
->
old_info
);
ioctl
(
sys
->
fd
,
FBIOPUT_VSCREENINFO
,
&
sys
->
old_info
);
/* Close fb */
close
(
p_vout
->
p_sys
->
i_fd
);
close
(
sys
->
fd
);
}
}
...
...
@@ -925,37 +674,37 @@ static void CloseDisplay( vout_thread_t *p_vout )
* This function activates or deactivates the output of the thread. It is
* called by the VT driver, on terminal change.
*****************************************************************************/
static
void
SwitchDisplay
(
int
i_signal
)
static
void
SwitchDisplay
(
int
i_signal
)
{
VLC_UNUSED
(
i_signal
);
VLC_UNUSED
(
i_signal
);
#if 0
vout_
thread_t *p_vout
;
vout_
display_t *vd
;
vlc_mutex_lock(
&p_vout_bank->lock
);
vlc_mutex_lock(
&p_vout_bank->lock
);
/* XXX: only test the first video output */
if
( p_vout_bank->i_count
)
if
(p_vout_bank->i_count
)
{
p_vout
= p_vout_bank->pp_vout[0];
vd
= p_vout_bank->pp_vout[0];
switch
( i_signal
)
switch
(i_signal
)
{
case SIGUSR1: /* vt has been released */
p_vout
->b_active = 0;
ioctl(
p_sys->i_tty, VT_RELDISP, 1
);
vd
->b_active = 0;
ioctl(
sys->tty, VT_RELDISP, 1
);
break;
case SIGUSR2: /* vt has been acquired */
p_vout
->b_active = 1;
ioctl(
p_sys->i_tty, VT_RELDISP, VT_ACTIVATE
);
vd
->b_active = 1;
ioctl(
sys->tty, VT_RELDISP, VT_ACTIVATE
);
/* handle blanking */
vlc_mutex_lock(
&p_vout->change_lock
);
p_vout
->i_changes |= VOUT_SIZE_CHANGE;
vlc_mutex_unlock(
&p_vout->change_lock
);
vlc_mutex_lock(
&vd->change_lock
);
vd
->i_changes |= VOUT_SIZE_CHANGE;
vlc_mutex_unlock(
&vd->change_lock
);
break;
}
}
vlc_mutex_unlock(
&p_vout_bank->lock
);
vlc_mutex_unlock(
&p_vout_bank->lock
);
#endif
}
...
...
@@ -964,20 +713,18 @@ static void SwitchDisplay( int i_signal )
*****************************************************************************
* These functions toggle the tty mode.
*****************************************************************************/
static
void
TextMode
(
int
i_tty
)
static
void
TextMode
(
int
tty
)
{
/* return to text mode */
if
(
-
1
==
ioctl
(
i_tty
,
KDSETMODE
,
KD_TEXT
)
)
{
/*msg_Err( p_vout, "failed ioctl KDSETMODE KD_TEXT" );*/
if
(
-
1
==
ioctl
(
tty
,
KDSETMODE
,
KD_TEXT
))
{
/*msg_Err(vd, "failed ioctl KDSETMODE KD_TEXT");*/
}
}
static
void
GfxMode
(
int
i_tty
)
static
void
GfxMode
(
int
tty
)
{
/* switch to graphic mode */
if
(
-
1
==
ioctl
(
i_tty
,
KDSETMODE
,
KD_GRAPHICS
)
)
{
/*msg_Err( p_vout, "failed ioctl KDSETMODE KD_GRAPHICS" );*/
if
(
-
1
==
ioctl
(
tty
,
KDSETMODE
,
KD_GRAPHICS
))
{
/*msg_Err(vd, "failed ioctl KDSETMODE KD_GRAPHICS");*/
}
}
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