Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
405acb8a
Commit
405acb8a
authored
Sep 02, 2009
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Converted yuv to "vout display" API.
parent
42fbb6d8
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
194 additions
and
239 deletions
+194
-239
modules/video_output/yuv.c
modules/video_output/yuv.c
+194
-239
No files found.
modules/video_output/yuv.c
View file @
405acb8a
...
@@ -31,303 +31,258 @@
...
@@ -31,303 +31,258 @@
#include <vlc_common.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_plugin.h>
#include <vlc_vout.h>
#include <vlc_vout_display.h>
#include <vlc_picture_pool.h>
#include <vlc_charset.h>
#include <vlc_charset.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
*
p_vout
);
static
void
Display
(
vout_thread_t
*
,
picture_t
*
);
/*****************************************************************************
/*****************************************************************************
* Module descriptor
* Module descriptor
*****************************************************************************/
*****************************************************************************/
#define YUV_FILE_TEXT N_("device, fifo or filename")
#define YUV_FILE_TEXT N_("device, fifo or filename")
#define YUV_FILE_LONGTEXT N_("device, fifo or filename to write yuv frames too."
)
#define YUV_FILE_LONGTEXT N_("device, fifo or filename to write yuv frames too.")
#define CHROMA_TEXT N_("Chroma used.")
#define CHROMA_TEXT N_("Chroma used.")
#define CHROMA_LONGTEXT N_(
\
#define CHROMA_LONGTEXT N_(\
"Force use of a specific chroma for output. Default is I420."
)
"Force use of a specific chroma for output. Default is I420.")
#define YUV4MPEG2_TEXT N_(
"YUV4MPEG2 header (default disabled)"
)
#define YUV4MPEG2_TEXT N_(
"YUV4MPEG2 header (default disabled)"
)
#define YUV4MPEG2_LONGTEXT N_(
"The YUV4MPEG2 header is compatible " \
#define YUV4MPEG2_LONGTEXT N_("The YUV4MPEG2 header is compatible " \
"with mplayer yuv video ouput and requires YV12/I420 fourcc. By default "\
"with mplayer yuv video ouput and requires YV12/I420 fourcc. By default "\
"vlc writes the fourcc of the picture frame into the output destination."
)
"vlc writes the fourcc of the picture frame into the output destination.")
#define CFG_PREFIX "yuv-"
#define CFG_PREFIX "yuv-"
vlc_module_begin
()
static
int
Open
(
vlc_object_t
*
);
set_shortname
(
N_
(
"YUV output"
)
)
static
void
Close
(
vlc_object_t
*
);
set_description
(
N_
(
"YUV video output"
)
)
set_category
(
CAT_VIDEO
)
vlc_module_begin
()
set_subcategory
(
SUBCAT_VIDEO_VOUT
)
set_shortname
(
N_
(
"YUV output"
))
set_capability
(
"video output"
,
0
)
set_description
(
N_
(
"YUV video output"
))
set_category
(
CAT_VIDEO
)
set_subcategory
(
SUBCAT_VIDEO_VOUT
)
set_capability
(
"vout display"
,
0
)
add_string
(
CFG_PREFIX
"file"
,
"stream.yuv"
,
NULL
,
add_string
(
CFG_PREFIX
"file"
,
"stream.yuv"
,
NULL
,
YUV_FILE_TEXT
,
YUV_FILE_LONGTEXT
,
false
)
YUV_FILE_TEXT
,
YUV_FILE_LONGTEXT
,
false
)
add_string
(
CFG_PREFIX
"chroma"
,
NULL
,
NULL
,
add_string
(
CFG_PREFIX
"chroma"
,
NULL
,
NULL
,
CHROMA_TEXT
,
CHROMA_LONGTEXT
,
true
)
CHROMA_TEXT
,
CHROMA_LONGTEXT
,
true
)
add_bool
(
CFG_PREFIX
"yuv4mpeg2"
,
false
,
NULL
,
add_bool
(
CFG_PREFIX
"yuv4mpeg2"
,
false
,
NULL
,
YUV4MPEG2_TEXT
,
YUV4MPEG2_LONGTEXT
,
true
)
YUV4MPEG2_TEXT
,
YUV4MPEG2_LONGTEXT
,
true
)
set_callbacks
(
Create
,
Destroy
)
set_callbacks
(
Open
,
Close
)
vlc_module_end
()
vlc_module_end
()
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static
const
char
*
const
ppsz_vout_options
[]
=
{
static
const
char
*
const
ppsz_vout_options
[]
=
{
"file"
,
"chroma"
,
"yuv4mpeg2"
,
NULL
"file"
,
"chroma"
,
"yuv4mpeg2"
,
NULL
};
};
static
void
WriteYUV
(
vout_thread_t
*
p_vout
,
video_format_t
fmt
,
/* */
picture_t
*
p_pic
);
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
*
);
/*****************************************************************************
/*****************************************************************************
* vout_sys_t: video output descriptor
* vout_
display_
sys_t: video output descriptor
*****************************************************************************/
*****************************************************************************/
struct
vout_
sys_t
struct
vout_
display_sys_t
{
{
FILE
*
f
;
char
*
psz_file
;
bool
is_first
;
FILE
*
p_fd
;
bool
is_yuv4mpeg2
;
bool
b_heade
r
;
bool
use_d
r
;
bool
b_yuv4mpeg2
;
vlc_fourcc_t
i_chroma
;
picture_pool_t
*
pool
;
};
};
/*****************************************************************************
/* */
* Create: allocates video thread
static
int
Open
(
vlc_object_t
*
object
)
*****************************************************************************
* This function allocates and initializes a vout method.
*****************************************************************************/
static
int
Create
(
vlc_object_t
*
p_this
)
{
{
vout_thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_this
;
vout_display_t
*
vd
=
(
vout_display_t
*
)
object
;
vout_sys_t
*
p_sys
;
vout_display_sys_t
*
sys
;
char
*
psz_fcc
;
config_ChainParse
(
p_vout
,
CFG_PREFIX
,
ppsz_vout_options
,
p_vout
->
p_cfg
);
/* Allocate instance and initialize some members */
/* Allocate instance and initialize some members */
p_vout
->
p_sys
=
p_sys
=
malloc
(
sizeof
(
vout_sys_t
)
);
vd
->
sys
=
sys
=
malloc
(
sizeof
(
*
sys
)
);
if
(
!
p_vout
->
p_sys
)
if
(
!
sys
)
return
VLC_ENOMEM
;
return
VLC_ENOMEM
;
p_sys
->
b_header
=
false
;
sys
->
is_first
=
false
;
p_sys
->
p_fd
=
NULL
;
sys
->
is_yuv4mpeg2
=
var_CreateGetBool
(
vd
,
CFG_PREFIX
"yuv4mpeg2"
);
sys
->
pool
=
NULL
;
p_sys
->
b_yuv4mpeg2
=
var_CreateGetBool
(
p_this
,
CFG_PREFIX
"yuv4mpeg2"
);
/* */
p_sys
->
i_chroma
=
VLC_CODEC_I420
;
char
*
psz_fcc
=
var_CreateGetNonEmptyString
(
vd
,
CFG_PREFIX
"chroma"
);
const
vlc_fourcc_t
requested_chroma
=
vlc_fourcc_GetCodecFromString
(
VIDEO_ES
,
p_sys
->
psz_file
=
psz_fcc
);
var_CreateGetString
(
p_this
,
CFG_PREFIX
"file"
);
free
(
psz_fcc
);
p_sys
->
p_fd
=
utf8_fopen
(
p_sys
->
psz_file
,
"wb"
);
if
(
!
p_sys
->
p_fd
)
{
free
(
p_sys
->
psz_file
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
psz_fcc
=
var_CreateGetNonEmptyString
(
p_this
,
CFG_PREFIX
"chroma"
);
const
vlc_fourcc_t
chroma
=
requested_chroma
?
requested_chroma
:
const
vlc_fourcc_t
i_requested_chroma
=
VLC_CODEC_I420
;
vlc_fourcc_GetCodecFromString
(
VIDEO_ES
,
psz_fcc
);
if
(
sys
->
is_yuv4mpeg2
)
{
if
(
i_requested_chroma
)
switch
(
chroma
)
{
p_sys
->
i_chroma
=
i_requested_chroma
;
free
(
psz_fcc
);
if
(
p_sys
->
b_yuv4mpeg2
)
{
switch
(
p_sys
->
i_chroma
)
{
case
VLC_CODEC_YV12
:
case
VLC_CODEC_YV12
:
case
VLC_CODEC_I420
:
case
VLC_CODEC_I420
:
case
VLC_CODEC_J420
:
case
VLC_CODEC_J420
:
break
;
break
;
default:
default:
msg_Err
(
p_this
,
msg_Err
(
vd
,
"YUV4MPEG2 mode needs chroma YV12 not %4.4s as requested"
,
"YUV4MPEG2 mode needs chroma YV12 not %4s as requested"
,
(
char
*
)
&
chroma
);
(
char
*
)
&
(
p_sys
->
i_chroma
)
);
free
(
sys
);
fclose
(
p_vout
->
p_sys
->
p_fd
);
free
(
p_vout
->
p_sys
->
psz_file
);
free
(
p_vout
->
p_sys
);
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
}
}
sys
->
use_dr
=
chroma
==
vd
->
fmt
.
i_chroma
;
msg_Dbg
(
p_this
,
"using chroma %4s"
,
(
char
*
)
&
(
p_sys
->
i_chroma
)
);
msg_Dbg
(
vd
,
"Using chroma %4.4s"
,
(
char
*
)
&
chroma
);
p_vout
->
pf_init
=
Init
;
/* */
p_vout
->
pf_end
=
End
;
char
*
name
=
var_CreateGetNonEmptyString
(
vd
,
CFG_PREFIX
"file"
);
p_vout
->
pf_manage
=
NULL
;
if
(
!
name
)
{
p_vout
->
pf_render
=
NULL
;
msg_Err
(
vd
,
"Empty file name"
);
p_vout
->
pf_display
=
Display
;
free
(
sys
);
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Init: initialize video thread
*****************************************************************************/
static
int
Init
(
vout_thread_t
*
p_vout
)
{
vout_sys_t
*
p_sys
=
(
vout_sys_t
*
)
p_vout
->
p_sys
;
int
i_index
;
picture_t
*
p_pic
;
/* Initialize the output structure */
if
(
p_vout
->
render
.
i_chroma
!=
p_sys
->
i_chroma
)
p_vout
->
output
.
i_chroma
=
p_vout
->
fmt_out
.
i_chroma
=
p_sys
->
i_chroma
;
else
p_vout
->
output
.
i_chroma
=
p_vout
->
render
.
i_chroma
;
p_vout
->
output
.
pf_setpalette
=
NULL
;
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
->
output
.
i_width
*
VOUT_ASPECT_FACTOR
/
p_vout
->
output
.
i_height
;
p_vout
->
output
.
i_rmask
=
0xff0000
;
p_vout
->
output
.
i_gmask
=
0x00ff00
;
p_vout
->
output
.
i_bmask
=
0x0000ff
;
/* 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
;
return
VLC_EGENERIC
;
}
sys
->
f
=
utf8_fopen
(
name
,
"wb"
);
vout_AllocatePicture
(
VLC_OBJECT
(
p_vout
),
p_pic
,
p_vout
->
output
.
i_chroma
,
if
(
!
sys
->
f
)
{
p_vout
->
output
.
i_width
,
p_vout
->
output
.
i_height
,
msg_Err
(
vd
,
"Failed to open %s"
,
name
);
p_vout
->
output
.
i_aspect
);
free
(
name
);
free
(
sys
);
if
(
p_pic
->
i_planes
==
0
)
{
return
VLC_EGENERIC
;
return
VLC_EGENERIC
;
}
}
msg_Dbg
(
vd
,
"Writing data to %s"
,
name
);
p_pic
->
i_status
=
DESTROYED_PICTURE
;
free
(
name
);
p_pic
->
i_type
=
DIRECT_PICTURE
;
/* */
PP_OUTPUTPICTURE
[
I_OUTPUTPICTURES
]
=
p_pic
;
video_format_t
fmt
=
vd
->
fmt
;
I_OUTPUTPICTURES
++
;
fmt
.
i_chroma
=
chroma
;
video_format_FixRgb
(
&
fmt
);
/* */
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
,
false
);
return
VLC_SUCCESS
;
return
VLC_SUCCESS
;
}
}
/*****************************************************************************
/* */
* Destroy: destroy video thread
static
void
Close
(
vlc_object_t
*
object
)
*****************************************************************************
* Terminate an output method created by Create
*****************************************************************************/
static
void
Destroy
(
vlc_object_t
*
p_this
)
{
{
int
i_index
;
vout_display_t
*
vd
=
(
vout_display_t
*
)
object
;
vout_
thread_t
*
p_vout
=
(
vout_thread_t
*
)
p_thi
s
;
vout_
display_sys_t
*
sys
=
vd
->
sy
s
;
for
(
i_index
=
I_OUTPUTPICTURES
-
1
;
i_index
>=
0
;
i_index
--
)
if
(
sys
->
pool
)
{
picture_pool_Delete
(
sys
->
pool
);
free
(
PP_OUTPUTPICTURE
[
i_index
]
->
p_data
);
fclose
(
sys
->
f
);
}
free
(
sys
);
/* Destroy structure */
fclose
(
p_vout
->
p_sys
->
p_fd
);
free
(
p_vout
->
p_sys
->
psz_file
);
free
(
p_vout
->
p_sys
);
}
}
/*****************************************************************************
/*****************************************************************************
* Display: displays previously rendered output
*
*****************************************************************************
* This function copies the rendered picture into our circular buffer.
*****************************************************************************/
*****************************************************************************/
static
void
Display
(
vout_thread_t
*
p_vout
,
picture_t
*
p_pic
)
static
picture_t
*
Get
(
vout_display_t
*
vd
)
{
{
video_format_t
fmt_in
;
vout_display_sys_t
*
sys
=
vd
->
sys
;
if
(
!
sys
->
pool
)
{
memset
(
&
fmt_in
,
0
,
sizeof
(
fmt_in
)
);
sys
->
pool
=
picture_pool_NewFromFormat
(
&
vd
->
fmt
,
sys
->
use_dr
?
VOUT_MAX_PICTURES
:
1
);
video_format_Copy
(
&
fmt_in
,
&
p_pic
->
format
);
if
(
!
sys
->
pool
)
/* assume square pixels if i_sar_num = 0 */
return
NULL
;
if
(
p_pic
->
format
.
i_sar_num
==
0
)
}
fmt_in
.
i_sar_num
=
fmt_in
.
i_sar_den
=
1
;
return
picture_pool_Get
(
sys
->
pool
);
WriteYUV
(
p_vout
,
fmt_in
,
p_pic
);
video_format_Clean
(
&
fmt_in
);
return
;
}
static
void
End
(
vout_thread_t
*
p_vout
)
{
VLC_UNUSED
(
p_vout
);
}
}
static
void
WriteYUV
(
vout_thread_t
*
p_vout
,
video_format_t
fmt
,
static
void
Display
(
vout_display_t
*
vd
,
picture_t
*
picture
)
picture_t
*
p_pic
)
{
{
vout_sys_t
*
p_sys
=
p_vout
->
p_sys
;
vout_display_sys_t
*
sys
=
vd
->
sys
;
/* */
video_format_t
fmt
=
vd
->
fmt
;
fmt
.
i_sar_num
=
vd
->
source
.
i_sar_num
;
fmt
.
i_sar_den
=
vd
->
source
.
i_sar_den
;
/* */
char
type
;
if
(
picture
->
b_progressive
)
type
=
'p'
;
else
if
(
picture
->
b_top_field_first
)
type
=
't'
;
else
type
=
'b'
;
if
(
!
p_pic
||
!
p_sys
)
return
;
if
(
type
!=
'p'
)
{
msg_Warn
(
vd
,
"Received a non progressive frame, "
"it will be written as progressive."
);
type
=
'p'
;
}
#if 0
/* */
msg_Dbg( p_vout, "writing %d bytes of fourcc %4s",
if
(
!
sys
->
is_first
)
{
i_bytes, (char *)&fmt.i_chroma );
const
char
*
header
;
#endif
char
buffer
[
5
];
if
(
!
p_sys
->
b_header
)
if
(
sys
->
is_yuv4mpeg2
)
{
{
const
char
*
p_hdr
=
""
;
if
(
p_sys
->
b_yuv4mpeg2
)
{
/* MPlayer compatible header, unfortunately it doesn't tell you
/* MPlayer compatible header, unfortunately it doesn't tell you
* the exact fourcc used. */
* the exact fourcc used. */
p_hd
r
=
"YUV4MPEG2"
;
heade
r
=
"YUV4MPEG2"
;
}
}
else
{
else
snprintf
(
buffer
,
sizeof
(
buffer
),
"%4.4s"
,
{
(
const
char
*
)
&
fmt
.
i_chroma
);
p_hdr
=
(
const
char
*
)
&
fmt
.
i_chroma
;
header
=
buffer
;
}
}
fprintf
(
p_sys
->
p_fd
,
"%4s W%d H%d F%d:%d I%c A%d:%d
\n
"
,
p_hdr
,
fprintf
(
sys
->
f
,
"%s W%d H%d F%d:%d I%c A%d:%d
\n
"
,
fmt
.
i_width
,
fmt
.
i_height
,
header
,
fmt
.
i_visible_width
,
fmt
.
i_visible_height
,
fmt
.
i_frame_rate
,
fmt
.
i_frame_rate_base
,
fmt
.
i_frame_rate
,
fmt
.
i_frame_rate_base
,
(
p_pic
->
b_progressive
?
'p'
:
type
,
(
p_pic
->
b_top_field_first
?
't'
:
'b'
)),
fmt
.
i_sar_num
,
fmt
.
i_sar_den
);
fmt
.
i_sar_num
,
fmt
.
i_sar_den
);
sys
->
is_first
=
true
;
fflush
(
p_sys
->
p_fd
);
p_sys
->
b_header
=
true
;
}
}
fprintf
(
p_sys
->
p_fd
,
"FRAME
\n
"
);
/* */
if
(
p_pic
->
b_progressive
)
fprintf
(
sys
->
f
,
"FRAME
\n
"
);
{
for
(
int
i
=
0
;
i
<
picture
->
i_planes
;
i
++
)
{
size_t
i_bytes
=
(
fmt
.
i_width
*
fmt
.
i_height
*
fmt
.
i_bits_per_pixel
)
>>
3
;
const
plane_t
*
plane
=
&
picture
->
p
[
i
];
size_t
i_written
=
0
;
for
(
int
y
=
0
;
y
<
plane
->
i_visible_lines
;
y
++
)
{
const
size_t
written
=
fwrite
(
&
plane
->
p_pixels
[
y
*
plane
->
i_pitch
],
i_written
=
fwrite
(
p_pic
->
p_data
,
1
,
i_bytes
,
p_sys
->
p_fd
);
1
,
plane
->
i_visible_pitch
,
sys
->
f
);
if
(
i_written
!=
i_bytes
)
if
(
written
!=
(
size_t
)
plane
->
i_visible_pitch
)
{
msg_Warn
(
vd
,
"only %zd of %d bytes written"
,
msg_Warn
(
p_vout
,
"only %zd of %zd bytes written"
,
written
,
plane
->
i_visible_pitch
);
i_written
,
i_bytes
);
}
}
}
}
else
fflush
(
sys
->
f
);
{
msg_Warn
(
p_vout
,
"only progressive frames are supported, "
/* */
"use a deinterlace filter"
);
picture_Release
(
picture
);
}
static
int
Control
(
vout_display_t
*
vd
,
int
query
,
va_list
args
)
{
VLC_UNUSED
(
vd
);
switch
(
query
)
{
case
VOUT_DISPLAY_CHANGE_FULLSCREEN
:
{
const
vout_display_cfg_t
*
cfg
=
va_arg
(
args
,
const
vout_display_cfg_t
*
);
if
(
cfg
->
is_fullscreen
)
return
VLC_EGENERIC
;
return
VLC_SUCCESS
;
}
default:
return
VLC_EGENERIC
;
}
}
fflush
(
p_sys
->
p_fd
);
}
}
static
void
Manage
(
vout_display_t
*
vd
)
{
VLC_UNUSED
(
vd
);
}
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