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
d4a124a3
Commit
d4a124a3
authored
Feb 04, 2016
by
Tristan Matthews
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
vpx: add vp8 and vp9 encoder
parent
ea705c60
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
195 additions
and
2 deletions
+195
-2
NEWS
NEWS
+1
-0
configure.ac
configure.ac
+7
-1
modules/MODULES_LIST
modules/MODULES_LIST
+1
-1
modules/codec/vpx.c
modules/codec/vpx.c
+186
-0
No files found.
NEWS
View file @
d4a124a3
...
...
@@ -131,6 +131,7 @@ Stream Output:
Encoder:
* Support for Daala video in 4:2:0 and 4:4:4
* VP8 and VP9 encoder using libvpx
Muxers:
* Added fragmented/streamable MP4 muxer
...
...
configure.ac
View file @
d4a124a3
...
...
@@ -2627,7 +2627,7 @@ dnl
dnl libvpx decoder plugin
dnl
AC_ARG_ENABLE(vpx,
AS_HELP_STRING([--enable-vpx],[libvpx VP8/VP9 decoder (default auto)]))
AS_HELP_STRING([--enable-vpx],[libvpx VP8/VP9
encoder and
decoder (default auto)]))
AS_IF([test "${enable_vpx}" != "no"],[
PKG_CHECK_MODULES([VPX], [vpx] , [
VLC_ADD_PLUGIN([vpx])
...
...
@@ -2639,6 +2639,12 @@ AS_IF([test "${enable_vpx}" != "no"],[
AC_CHECK_LIB([vpx],[vpx_codec_vp9_dx], [
VLC_ADD_CPPFLAGS([vpx], [-DENABLE_VP9_DECODER])
], [], [${VPX_LIBS}])
AC_CHECK_LIB([vpx],[vpx_codec_vp8_cx], [
VLC_ADD_CPPFLAGS([vpx], [-DENABLE_VP8_ENCODER])
], [], [${VPX_LIBS}])
AC_CHECK_LIB([vpx],[vpx_codec_vp9_cx], [
VLC_ADD_CPPFLAGS([vpx], [-DENABLE_VP9_ENCODER])
], [], [${VPX_LIBS}])
], [
AS_IF([test "${enable_vpx}" = "yes"],[
AC_MSG_ERROR([libvpx was not found])
...
...
modules/MODULES_LIST
View file @
d4a124a3
...
...
@@ -438,7 +438,7 @@ $Id$
* vout_ios2: iOS video provider using OpenGL ES 2
* vout_macosx: Mac OS X OpenGL provider
* vout_sdl: video output module using the SDL library
* vpx: WebM decoder (VP8/VP9)
* vpx: WebM
encoder and
decoder (VP8/VP9)
* vsxu: audio visualization using Vovoid VSXu
* wall: image wall filter
* wasapi: Wasapi audio output module
...
...
modules/codec/vpx.c
View file @
d4a124a3
...
...
@@ -34,11 +34,28 @@
#include <vpx/vpx_decoder.h>
#include <vpx/vp8dx.h>
#ifdef ENABLE_SOUT
# include <vpx/vpx_encoder.h>
# include <vpx/vp8cx.h>
#endif
/****************************************************************************
* Local prototypes
****************************************************************************/
static
const
char
*
const
ppsz_sout_options
[]
=
{
"quality-mode"
,
NULL
};
static
int
OpenDecoder
(
vlc_object_t
*
);
static
void
CloseDecoder
(
vlc_object_t
*
);
#ifdef ENABLE_SOUT
static
int
OpenEncoder
(
vlc_object_t
*
);
static
void
CloseEncoder
(
vlc_object_t
*
);
static
block_t
*
Encode
(
encoder_t
*
p_enc
,
picture_t
*
p_pict
);
#define QUALITY_MODE_TEXT N_("Quality mode")
#define QUALITY_MODE_LONGTEXT N_("Quality setting which will determine max encoding time, default 0\n" \
" - 0: Good quality\n"\
" - 1: Realtime\n"\
" - 2: Best quality")
#endif
/*****************************************************************************
* Module descriptor
...
...
@@ -51,6 +68,17 @@ vlc_module_begin ()
set_callbacks
(
OpenDecoder
,
CloseDecoder
)
set_category
(
CAT_INPUT
)
set_subcategory
(
SUBCAT_INPUT_VCODEC
)
#ifdef ENABLE_SOUT
add_submodule
()
set_shortname
(
"vpx"
)
set_capability
(
"encoder"
,
60
)
set_description
(
N_
(
"WebM video encoder"
))
set_callbacks
(
OpenEncoder
,
CloseEncoder
)
# define ENC_CFG_PREFIX "sout-vpx-"
add_integer
(
ENC_CFG_PREFIX
"quality-mode"
,
VPX_DL_GOOD_QUALITY
,
QUALITY_MODE_TEXT
,
QUALITY_MODE_LONGTEXT
,
true
)
change_integer_range
(
0
,
2
)
#endif
vlc_module_end
()
static
void
vpx_err_msg
(
vlc_object_t
*
this
,
struct
vpx_codec_ctx
*
ctx
,
...
...
@@ -235,3 +263,161 @@ static void CloseDecoder(vlc_object_t *p_this)
free
(
sys
);
}
#ifdef ENABLE_SOUT
/*****************************************************************************
* encoder_sys_t: libvpx encoder descriptor
*****************************************************************************/
struct
encoder_sys_t
{
struct
vpx_codec_ctx
ctx
;
};
/*****************************************************************************
* OpenEncoder: probe the encoder
*****************************************************************************/
static
int
OpenEncoder
(
vlc_object_t
*
p_this
)
{
encoder_t
*
p_enc
=
(
encoder_t
*
)
p_this
;
encoder_sys_t
*
p_sys
;
/* Allocate the memory needed to store the encoder's structure */
p_sys
=
malloc
(
sizeof
(
*
p_sys
));
if
(
p_sys
==
NULL
)
return
VLC_ENOMEM
;
p_enc
->
p_sys
=
p_sys
;
const
struct
vpx_codec_iface
*
iface
;
int
vp_version
;
switch
(
p_enc
->
fmt_out
.
i_codec
)
{
#ifdef ENABLE_VP8_ENCODER
case
VLC_CODEC_VP8
:
iface
=
&
vpx_codec_vp8_cx_algo
;
vp_version
=
8
;
break
;
#endif
#ifdef ENABLE_VP9_DECODER
case
VLC_CODEC_VP9
:
iface
=
&
vpx_codec_vp9_cx_algo
;
vp_version
=
9
;
break
;
#endif
default:
return
VLC_EGENERIC
;
}
struct
vpx_codec_enc_cfg
enccfg
=
{};
vpx_codec_enc_config_default
(
iface
,
&
enccfg
,
0
);
enccfg
.
g_threads
=
__MIN
(
vlc_GetCPUCount
(),
4
);
enccfg
.
g_w
=
p_enc
->
fmt_in
.
video
.
i_visible_width
;
enccfg
.
g_h
=
p_enc
->
fmt_in
.
video
.
i_visible_height
;
msg_Dbg
(
p_this
,
"VP%d: using libvpx version %s (build options %s)"
,
vp_version
,
vpx_codec_version_str
(),
vpx_codec_build_config
());
struct
vpx_codec_ctx
*
ctx
=
&
p_sys
->
ctx
;
if
(
vpx_codec_enc_init
(
ctx
,
iface
,
&
enccfg
,
0
)
!=
VPX_CODEC_OK
)
{
VPX_ERR
(
p_this
,
ctx
,
"Failed to initialize encoder"
);
free
(
p_sys
);
return
VLC_EGENERIC
;
}
p_enc
->
pf_encode_video
=
Encode
;
p_enc
->
fmt_in
.
i_codec
=
VLC_CODEC_I420
;
config_ChainParse
(
p_enc
,
ENC_CFG_PREFIX
,
ppsz_sout_options
,
p_enc
->
p_cfg
);
return
VLC_SUCCESS
;
}
/****************************************************************************
* Encode: the whole thing
****************************************************************************/
static
block_t
*
Encode
(
encoder_t
*
p_enc
,
picture_t
*
p_pict
)
{
encoder_sys_t
*
p_sys
=
p_enc
->
p_sys
;
struct
vpx_codec_ctx
*
ctx
=
&
p_sys
->
ctx
;
if
(
!
p_pict
)
return
NULL
;
vpx_image_t
img
=
{};
unsigned
i_w
=
p_enc
->
fmt_in
.
video
.
i_visible_width
;
unsigned
i_h
=
p_enc
->
fmt_in
.
video
.
i_visible_height
;
/* Create and initialize the vpx_image */
if
(
!
vpx_img_alloc
(
&
img
,
VPX_IMG_FMT_I420
,
i_w
,
i_h
,
1
))
{
VPX_ERR
(
p_enc
,
ctx
,
"Failed to allocate image"
);
return
NULL
;
}
for
(
int
plane
=
0
;
plane
<
p_pict
->
i_planes
;
plane
++
)
{
uint8_t
*
src
=
p_pict
->
p
[
plane
].
p_pixels
;
uint8_t
*
dst
=
img
.
planes
[
plane
];
int
src_stride
=
p_pict
->
p
[
plane
].
i_pitch
;
int
dst_stride
=
img
.
stride
[
plane
];
int
size
=
__MIN
(
src_stride
,
dst_stride
);
for
(
int
line
=
0
;
line
<
p_pict
->
p
[
plane
].
i_visible_lines
;
line
++
)
{
memcpy
(
dst
,
src
,
size
);
src
+=
src_stride
;
dst
+=
dst_stride
;
}
}
int
flags
=
0
;
/* Deadline (in ms) to spend in encoder */
int
quality
=
VPX_DL_GOOD_QUALITY
;
switch
(
var_GetInteger
(
p_enc
,
ENC_CFG_PREFIX
"quality-mode"
))
{
case
1
:
quality
=
VPX_DL_REALTIME
;
break
;
case
2
:
quality
=
VPX_DL_BEST_QUALITY
;
break
;
default:
break
;
}
vpx_codec_err_t
res
=
vpx_codec_encode
(
ctx
,
&
img
,
p_pict
->
date
,
1
,
flags
,
quality
);
if
(
res
!=
VPX_CODEC_OK
)
{
VPX_ERR
(
p_enc
,
ctx
,
"Failed to encode frame"
);
return
NULL
;
}
const
vpx_codec_cx_pkt_t
*
pkt
=
NULL
;
vpx_codec_iter_t
iter
=
NULL
;
block_t
*
p_out
=
NULL
;
while
((
pkt
=
vpx_codec_get_cx_data
(
ctx
,
&
iter
))
!=
NULL
)
{
if
(
pkt
->
kind
==
VPX_CODEC_CX_FRAME_PKT
)
{
int
keyframe
=
pkt
->
data
.
frame
.
flags
&
VPX_FRAME_IS_KEY
;
block_t
*
p_block
=
block_Alloc
(
pkt
->
data
.
frame
.
sz
);
memcpy
(
p_block
->
p_buffer
,
pkt
->
data
.
frame
.
buf
,
pkt
->
data
.
frame
.
sz
);
p_block
->
i_dts
=
p_block
->
i_pts
=
pkt
->
data
.
frame
.
pts
;
if
(
keyframe
)
p_block
->
i_flags
|=
BLOCK_FLAG_TYPE_I
;
block_ChainAppend
(
&
p_out
,
p_block
);
}
}
vpx_img_free
(
&
img
);
return
p_out
;
}
/*****************************************************************************
* CloseEncoder: encoder destruction
*****************************************************************************/
static
void
CloseEncoder
(
vlc_object_t
*
p_this
)
{
encoder_t
*
p_enc
=
(
encoder_t
*
)
p_this
;
encoder_sys_t
*
p_sys
=
p_enc
->
p_sys
;
if
(
vpx_codec_destroy
(
&
p_sys
->
ctx
))
VPX_ERR
(
p_this
,
&
p_sys
->
ctx
,
"Failed to destroy codec"
);
free
(
p_sys
);
}
#endif
/* ENABLE_SOUT */
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