Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
a6cf296b
Commit
a6cf296b
authored
Jun 24, 2012
by
Nicolas George
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavc: Opus decoder using libopus.
parent
e62fd661
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
230 additions
and
1 deletion
+230
-1
Changelog
Changelog
+1
-0
configure
configure
+5
-0
Makefile
libavcodec/Makefile
+1
-0
allcodecs.c
libavcodec/allcodecs.c
+1
-0
libopus_dec.c
libavcodec/libopus_dec.c
+221
-0
version.h
libavcodec/version.h
+1
-1
No files found.
Changelog
View file @
a6cf296b
...
...
@@ -32,6 +32,7 @@ version next:
- 3GPP Timed Text decoder
- GeoTIFF decoder support
- ffmpeg -(no)stdin option
- Opus decoder using libopus
version 0.11:
...
...
configure
View file @
a6cf296b
...
...
@@ -191,6 +191,7 @@ External library support:
--enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
--enable-libopencv enable video filtering via libopencv [no]
--enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no]
--enable-libopus enable Opus decoding via libopus [no]
--enable-libpulse enable Pulseaudio input via libpulse [no]
--enable-librtmp enable RTMP[E] support via librtmp [no]
--enable-libschroedinger enable Dirac de/encoding via libschroedinger [no]
...
...
@@ -1066,6 +1067,7 @@ CONFIG_LIST="
libopencore_amrwb
libopencv
libopenjpeg
libopus
libpulse
librtmp
libschroedinger
...
...
@@ -1635,6 +1637,7 @@ libopencore_amrnb_encoder_deps="libopencore_amrnb"
libopencore_amrwb_decoder_deps
=
"libopencore_amrwb"
libopenjpeg_decoder_deps
=
"libopenjpeg"
libopenjpeg_encoder_deps
=
"libopenjpeg"
libopus_decoder_deps
=
"libopus"
libschroedinger_decoder_deps
=
"libschroedinger"
libschroedinger_encoder_deps
=
"libschroedinger"
libspeex_decoder_deps
=
"libspeex"
...
...
@@ -3321,6 +3324,7 @@ enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_de
enabled libopencore_amrwb
&&
require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init
-lopencore-amrwb
enabled libopencv
&&
require_pkg_config opencv opencv/cxcore.h cvCreateImageHeader
enabled libopenjpeg
&&
require libopenjpeg openjpeg.h opj_version
-lopenjpeg
enabled libopus
&&
require_pkg_config opus opus_multistream.h opus_multistream_decoder_create
enabled libpulse
&&
require_pkg_config libpulse-simple pulse/simple.h pa_simple_new
enabled librtmp
&&
require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket
enabled libschroedinger
&&
require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init
...
...
@@ -3699,6 +3703,7 @@ echo "libopencore-amrnb support ${libopencore_amrnb-no}"
echo
"libopencore-amrwb support
${
libopencore_amrwb
-no
}
"
echo
"libopencv support
${
libopencv
-no
}
"
echo
"libopenjpeg enabled
${
libopenjpeg
-no
}
"
echo
"libopus enabled
${
libopus
-no
}
"
echo
"libpulse enabled
${
libpulse
-no
}
"
echo
"librtmp enabled
${
librtmp
-no
}
"
echo
"libschroedinger enabled
${
libschroedinger
-no
}
"
...
...
libavcodec/Makefile
View file @
a6cf296b
...
...
@@ -684,6 +684,7 @@ OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o \
OBJS-$(CONFIG_LIBOPENCORE_AMRWB_DECODER)
+=
libopencore-amr.o
OBJS-$(CONFIG_LIBOPENJPEG_DECODER)
+=
libopenjpegdec.o
OBJS-$(CONFIG_LIBOPENJPEG_ENCODER)
+=
libopenjpegenc.o
OBJS-$(CONFIG_LIBOPUS_DECODER)
+=
libopus_dec.o
vorbis_data.o
OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER)
+=
libschroedingerdec.o
\
libschroedinger.o
OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER)
+=
libschroedingerenc.o
\
...
...
libavcodec/allcodecs.c
View file @
a6cf296b
...
...
@@ -427,6 +427,7 @@ void avcodec_register_all(void)
REGISTER_ENCDEC
(
LIBOPENCORE_AMRNB
,
libopencore_amrnb
);
REGISTER_DECODER
(
LIBOPENCORE_AMRWB
,
libopencore_amrwb
);
REGISTER_ENCDEC
(
LIBOPENJPEG
,
libopenjpeg
);
REGISTER_DECODER
(
LIBOPUS
,
libopus
);
REGISTER_ENCDEC
(
LIBSCHROEDINGER
,
libschroedinger
);
REGISTER_ENCDEC
(
LIBSPEEX
,
libspeex
);
REGISTER_DECODER
(
LIBSTAGEFRIGHT_H264
,
libstagefright_h264
);
...
...
libavcodec/libopus_dec.c
0 → 100644
View file @
a6cf296b
/*
* Opus decoder using libopus
* Copyright (c) 2012 Nicolas George
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <opus.h>
#include <opus_multistream.h>
#include "avcodec.h"
#include "internal.h"
#include "vorbis.h"
#include "libavutil/avassert.h"
#include "libavutil/intreadwrite.h"
struct
libopus_context
{
OpusMSDecoder
*
dec
;
AVFrame
frame
;
int
pre_skip
;
#ifndef OPUS_SET_GAIN
union
{
int
i
;
double
d
;
}
gain
;
#endif
};
static
int
ff_opus_error_to_averror
(
int
err
)
{
switch
(
err
)
{
case
OPUS_BAD_ARG
:
return
AVERROR
(
EINVAL
);
case
OPUS_BUFFER_TOO_SMALL
:
return
AVERROR_BUFFER_TOO_SMALL
;
case
OPUS_INTERNAL_ERROR
:
return
AVERROR
(
EFAULT
);
case
OPUS_INVALID_PACKET
:
return
AVERROR_INVALIDDATA
;
case
OPUS_UNIMPLEMENTED
:
return
AVERROR
(
ENOSYS
);
case
OPUS_INVALID_STATE
:
return
AVERROR_EXTERNAL
;
case
OPUS_ALLOC_FAIL
:
return
AVERROR
(
ENOMEM
);
default:
return
AVERROR
(
EINVAL
);
}
}
static
inline
void
reorder
(
uint8_t
*
data
,
unsigned
channels
,
unsigned
bps
,
unsigned
samples
,
const
uint8_t
*
map
)
{
uint8_t
tmp
[
8
*
4
];
unsigned
i
;
av_assert1
(
channels
*
bps
<=
sizeof
(
tmp
));
for
(;
samples
>
0
;
samples
--
)
{
for
(
i
=
0
;
i
<
channels
;
i
++
)
memcpy
(
tmp
+
bps
*
i
,
data
+
bps
*
map
[
i
],
bps
);
memcpy
(
data
,
tmp
,
bps
*
channels
);
data
+=
bps
*
channels
;
}
}
#define OPUS_HEAD_SIZE 19
static
av_cold
int
libopus_dec_init
(
AVCodecContext
*
avc
)
{
struct
libopus_context
*
opus
=
avc
->
priv_data
;
int
ret
,
channel_map
=
0
,
gain_db
=
0
,
nb_streams
,
nb_coupled
;
uint8_t
mapping_stereo
[]
=
{
0
,
1
},
*
mapping
;
avc
->
sample_rate
=
48000
;
avc
->
sample_fmt
=
avc
->
request_sample_fmt
==
AV_SAMPLE_FMT_FLT
?
AV_SAMPLE_FMT_FLT
:
AV_SAMPLE_FMT_S16
;
avc
->
channel_layout
=
avc
->
channels
>
8
?
0
:
ff_vorbis_channel_layouts
[
avc
->
channels
-
1
];
if
(
avc
->
extradata_size
>=
OPUS_HEAD_SIZE
)
{
opus
->
pre_skip
=
AV_RL16
(
avc
->
extradata
+
10
);
gain_db
=
AV_RL16
(
avc
->
extradata
+
16
);
channel_map
=
AV_RL8
(
avc
->
extradata
+
18
);
gain_db
-=
(
gain_db
&
0x8000
)
<<
1
;
/* signed */
}
if
(
avc
->
extradata_size
>=
OPUS_HEAD_SIZE
+
2
+
avc
->
channels
)
{
nb_streams
=
avc
->
extradata
[
OPUS_HEAD_SIZE
+
0
];
nb_coupled
=
avc
->
extradata
[
OPUS_HEAD_SIZE
+
1
];
if
(
nb_streams
+
nb_coupled
!=
avc
->
channels
)
av_log
(
avc
,
AV_LOG_WARNING
,
"Inconsistent channel mapping.
\n
"
);
mapping
=
avc
->
extradata
+
OPUS_HEAD_SIZE
+
2
;
}
else
{
if
(
avc
->
channels
>
2
||
channel_map
)
{
av_log
(
avc
,
AV_LOG_ERROR
,
"No channel mapping for %d channels.
\n
"
,
avc
->
channels
);
return
AVERROR
(
EINVAL
);
}
nb_streams
=
1
;
nb_coupled
=
avc
->
channels
>
1
;
mapping
=
mapping_stereo
;
}
opus
->
dec
=
opus_multistream_decoder_create
(
avc
->
sample_rate
,
avc
->
channels
,
nb_streams
,
nb_coupled
,
mapping
,
&
ret
);
if
(
!
opus
->
dec
)
{
av_log
(
avc
,
AV_LOG_ERROR
,
"Unable to create decoder: %s
\n
"
,
opus_strerror
(
ret
));
return
ff_opus_error_to_averror
(
ret
);
}
#ifdef OPUS_SET_GAIN
ret
=
opus_multistream_decoder_ctl
(
opus
->
dec
,
OPUS_SET_GAIN
(
gain_db
));
if
(
ret
!=
OPUS_OK
)
av_log
(
avc
,
AV_LOG_WARNING
,
"Failed to set gain: %s
\n
"
,
opus_strerror
(
ret
));
#else
{
double
gain_lin
=
pow
(
10
,
gain_db
/
(
20
.
0
*
256
));
if
(
avc
->
sample_fmt
==
AV_SAMPLE_FMT_FLT
)
opus
->
gain
.
d
=
gain_lin
;
else
opus
->
gain
.
i
=
FFMIN
(
gain_lin
*
65536
,
INT_MAX
);
}
#endif
avc
->
internal
->
skip_samples
=
opus
->
pre_skip
;
avcodec_get_frame_defaults
(
&
opus
->
frame
);
avc
->
coded_frame
=
&
opus
->
frame
;
return
0
;
}
static
av_cold
int
libopus_dec_close
(
AVCodecContext
*
avc
)
{
struct
libopus_context
*
opus
=
avc
->
priv_data
;
opus_multistream_decoder_destroy
(
opus
->
dec
);
return
0
;
}
#define MAX_FRAME_SIZE (960*6)
static
int
libopus_dec_decode
(
AVCodecContext
*
avc
,
void
*
frame
,
int
*
got_frame_ptr
,
AVPacket
*
pkt
)
{
struct
libopus_context
*
opus
=
avc
->
priv_data
;
int
ret
,
nb_samples
;
opus
->
frame
.
nb_samples
=
MAX_FRAME_SIZE
;
ret
=
avc
->
get_buffer
(
avc
,
&
opus
->
frame
);
if
(
ret
<
0
)
{
av_log
(
avc
,
AV_LOG_ERROR
,
"get_buffer() failed
\n
"
);
return
ret
;
}
nb_samples
=
avc
->
sample_fmt
==
AV_SAMPLE_FMT_S16
?
opus_multistream_decode
(
opus
->
dec
,
pkt
->
data
,
pkt
->
size
,
(
void
*
)
opus
->
frame
.
data
[
0
],
opus
->
frame
.
nb_samples
,
0
)
:
opus_multistream_decode_float
(
opus
->
dec
,
pkt
->
data
,
pkt
->
size
,
(
void
*
)
opus
->
frame
.
data
[
0
],
opus
->
frame
.
nb_samples
,
0
);
if
(
nb_samples
<
0
)
{
av_log
(
avc
,
AV_LOG_ERROR
,
"Decoding error: %s
\n
"
,
opus_strerror
(
nb_samples
));
return
ff_opus_error_to_averror
(
nb_samples
);
}
if
(
avc
->
channels
>
3
&&
avc
->
channels
<=
8
)
{
const
uint8_t
*
m
=
ff_vorbis_channel_layout_offsets
[
avc
->
channels
-
1
];
if
(
avc
->
sample_fmt
==
AV_SAMPLE_FMT_S16
)
reorder
(
opus
->
frame
.
data
[
0
],
avc
->
channels
,
2
,
nb_samples
,
m
);
else
reorder
(
opus
->
frame
.
data
[
0
],
avc
->
channels
,
4
,
nb_samples
,
m
);
}
#ifndef OPUS_SET_GAIN
{
int
i
=
avc
->
channels
*
nb_samples
;
if
(
avc
->
sample_fmt
==
AV_SAMPLE_FMT_FLT
)
{
float
*
pcm
=
(
float
*
)
opus
->
frame
.
data
[
0
];
for
(;
i
>
0
;
i
--
,
pcm
++
)
*
pcm
=
av_clipf
(
*
pcm
*
opus
->
gain
.
d
,
-
1
,
1
);
}
else
{
int16_t
*
pcm
=
(
int16_t
*
)
opus
->
frame
.
data
[
0
];
for
(;
i
>
0
;
i
--
,
pcm
++
)
*
pcm
=
av_clip_int16
(((
int64_t
)
opus
->
gain
.
i
*
*
pcm
)
>>
16
);
}
}
#endif
opus
->
frame
.
nb_samples
=
nb_samples
;
*
(
AVFrame
*
)
frame
=
opus
->
frame
;
*
got_frame_ptr
=
1
;
return
pkt
->
size
;
}
static
void
libopus_dec_flush
(
AVCodecContext
*
avc
)
{
struct
libopus_context
*
opus
=
avc
->
priv_data
;
opus_multistream_decoder_ctl
(
opus
->
dec
,
OPUS_RESET_STATE
);
/* The stream can have been extracted by a tool that is not Opus-aware.
Therefore, any packet can become the first of the stream. */
avc
->
internal
->
skip_samples
=
opus
->
pre_skip
;
}
AVCodec
ff_libopus_decoder
=
{
.
name
=
"libopus"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
id
=
CODEC_ID_OPUS
,
.
priv_data_size
=
sizeof
(
struct
libopus_context
),
.
init
=
libopus_dec_init
,
.
close
=
libopus_dec_close
,
.
decode
=
libopus_dec_decode
,
.
flush
=
libopus_dec_flush
,
.
capabilities
=
CODEC_CAP_DR1
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"libopus Opus"
),
};
libavcodec/version.h
View file @
a6cf296b
...
...
@@ -27,7 +27,7 @@
*/
#define LIBAVCODEC_VERSION_MAJOR 54
#define LIBAVCODEC_VERSION_MINOR 4
1
#define LIBAVCODEC_VERSION_MINOR 4
2
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
...
...
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