Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
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
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
b606a017
Commit
b606a017
authored
Oct 18, 2011
by
Justin Ruggles
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libspeexenc: add libspeex encoder
parent
52375ba5
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
331 additions
and
4 deletions
+331
-4
Changelog
Changelog
+1
-0
configure
configure
+2
-1
general.texi
doc/general.texi
+1
-1
Makefile
libavcodec/Makefile
+1
-0
allcodecs.c
libavcodec/allcodecs.c
+1
-1
libspeexenc.c
libavcodec/libspeexenc.c
+324
-0
version.h
libavcodec/version.h
+1
-1
No files found.
Changelog
View file @
b606a017
...
...
@@ -53,6 +53,7 @@ easier to use. The changes are:
- lut, lutrgb, and lutyuv filters
- boxblur filter
- Ut Video decoder
- Speex encoding via libspeex
version 0.7:
...
...
configure
View file @
b606a017
...
...
@@ -178,7 +178,7 @@ External library support:
--enable-libopenjpeg enable JPEG 2000 decoding via OpenJPEG [no]
--enable-librtmp enable RTMP[E] support via librtmp [no]
--enable-libschroedinger enable Dirac support via libschroedinger [no]
--enable-libspeex enable Speex
decoding
via libspeex [no]
--enable-libspeex enable Speex
support
via libspeex [no]
--enable-libtheora enable Theora encoding via libtheora [no]
--enable-libvo-aacenc enable AAC encoding via libvo-aacenc [no]
--enable-libvo-amrwbenc enable AMR-WB encoding via libvo-amrwbenc [no]
...
...
@@ -1406,6 +1406,7 @@ libopenjpeg_decoder_deps="libopenjpeg"
libschroedinger_decoder_deps
=
"libschroedinger"
libschroedinger_encoder_deps
=
"libschroedinger"
libspeex_decoder_deps
=
"libspeex"
libspeex_encoder_deps
=
"libspeex"
libtheora_encoder_deps
=
"libtheora"
libvo_aacenc_encoder_deps
=
"libvo_aacenc"
libvo_amrwbenc_encoder_deps
=
"libvo_amrwbenc"
...
...
doc/general.texi
View file @
b606a017
...
...
@@ -682,7 +682,7 @@ following image formats are supported:
@tab Used in Sierra VMD files.
@item Smacker audio @tab @tab X
@item SMPTE 302M AES3 audio @tab @tab X
@item Speex @tab
@tab E
@item Speex @tab
E
@tab E
@tab supported through external library libspeex
@item True Audio (TTA) @tab @tab X
@item TrueHD @tab @tab X
...
...
libavcodec/Makefile
View file @
b606a017
...
...
@@ -576,6 +576,7 @@ OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o \
libschroedinger.o
\
libdirac_libschro.o
OBJS-$(CONFIG_LIBSPEEX_DECODER)
+=
libspeexdec.o
OBJS-$(CONFIG_LIBSPEEX_ENCODER)
+=
libspeexenc.o
OBJS-$(CONFIG_LIBTHEORA_ENCODER)
+=
libtheoraenc.o
OBJS-$(CONFIG_LIBVO_AACENC_ENCODER)
+=
libvo-aacenc.o
mpeg4audio.o
OBJS-$(CONFIG_LIBVO_AMRWBENC_ENCODER)
+=
libvo-amrwbenc.o
...
...
libavcodec/allcodecs.c
View file @
b606a017
...
...
@@ -370,7 +370,7 @@ void avcodec_register_all(void)
REGISTER_DECODER
(
LIBOPENCORE_AMRWB
,
libopencore_amrwb
);
REGISTER_DECODER
(
LIBOPENJPEG
,
libopenjpeg
);
REGISTER_ENCDEC
(
LIBSCHROEDINGER
,
libschroedinger
);
REGISTER_
DECODER
(
LIBSPEEX
,
libspeex
);
REGISTER_
ENCDEC
(
LIBSPEEX
,
libspeex
);
REGISTER_ENCODER
(
LIBTHEORA
,
libtheora
);
REGISTER_ENCODER
(
LIBVO_AACENC
,
libvo_aacenc
);
REGISTER_ENCODER
(
LIBVO_AMRWBENC
,
libvo_amrwbenc
);
...
...
libavcodec/libspeexenc.c
0 → 100644
View file @
b606a017
/*
* Copyright (C) 2009 Justin Ruggles
* Copyright (c) 2009 Xuggle Incorporated
*
* This file is part of Libav.
*
* Libav 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.
*
* Libav 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 Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* libspeex Speex audio encoder
*
* Usage Guide
* This explains the values that need to be set prior to initialization in
* order to control various encoding parameters.
*
* Channels
* Speex only supports mono or stereo, so avctx->channels must be set to
* 1 or 2.
*
* Sample Rate / Encoding Mode
* Speex has 3 modes, each of which uses a specific sample rate.
* narrowband : 8 kHz
* wideband : 16 kHz
* ultra-wideband : 32 kHz
* avctx->sample_rate must be set to one of these 3 values. This will be
* used to set the encoding mode.
*
* Rate Control
* VBR mode is turned on by setting CODEC_FLAG_QSCALE in avctx->flags.
* avctx->global_quality is used to set the encoding quality.
* For CBR mode, avctx->bit_rate can be used to set the constant bitrate.
* Alternatively, the 'cbr_quality' option can be set from 0 to 10 to set
* a constant bitrate based on quality.
* For ABR mode, set avctx->bit_rate and set the 'abr' option to 1.
* Approx. Bitrate Range:
* narrowband : 2400 - 25600 bps
* wideband : 4000 - 43200 bps
* ultra-wideband : 4400 - 45200 bps
*
* Complexity
* Encoding complexity is controlled by setting avctx->compression_level.
* The valid range is 0 to 10. A higher setting gives generally better
* quality at the expense of encoding speed. This does not affect the
* bit rate.
*
* Frames-per-Packet
* The encoder defaults to using 1 frame-per-packet. However, it is
* sometimes desirable to use multiple frames-per-packet to reduce the
* amount of container overhead. This can be done by setting the
* 'frames_per_packet' option to a value 1 to 8.
*/
#include <speex/speex.h>
#include <speex/speex_header.h>
#include <speex/speex_stereo.h>
#include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "internal.h"
typedef
struct
{
AVClass
*
class
;
///< AVClass for private options
SpeexBits
bits
;
///< libspeex bitwriter context
SpeexHeader
header
;
///< libspeex header struct
void
*
enc_state
;
///< libspeex encoder state
int
frames_per_packet
;
///< number of frames to encode in each packet
float
vbr_quality
;
///< VBR quality 0.0 to 10.0
int
cbr_quality
;
///< CBR quality 0 to 10
int
abr
;
///< flag to enable ABR
int
pkt_frame_count
;
///< frame count for the current packet
int
lookahead
;
///< encoder delay
int
sample_count
;
///< total sample count (used for pts)
}
LibSpeexEncContext
;
static
av_cold
void
print_enc_params
(
AVCodecContext
*
avctx
,
LibSpeexEncContext
*
s
)
{
const
char
*
mode_str
=
"unknown"
;
av_log
(
avctx
,
AV_LOG_DEBUG
,
"channels: %d
\n
"
,
avctx
->
channels
);
switch
(
s
->
header
.
mode
)
{
case
SPEEX_MODEID_NB
:
mode_str
=
"narrowband"
;
break
;
case
SPEEX_MODEID_WB
:
mode_str
=
"wideband"
;
break
;
case
SPEEX_MODEID_UWB
:
mode_str
=
"ultra-wideband"
;
break
;
}
av_log
(
avctx
,
AV_LOG_DEBUG
,
"mode: %s
\n
"
,
mode_str
);
if
(
s
->
header
.
vbr
)
{
av_log
(
avctx
,
AV_LOG_DEBUG
,
"rate control: VBR
\n
"
);
av_log
(
avctx
,
AV_LOG_DEBUG
,
" quality: %f
\n
"
,
s
->
vbr_quality
);
}
else
if
(
s
->
abr
)
{
av_log
(
avctx
,
AV_LOG_DEBUG
,
"rate control: ABR
\n
"
);
av_log
(
avctx
,
AV_LOG_DEBUG
,
" bitrate: %d bps
\n
"
,
avctx
->
bit_rate
);
}
else
{
av_log
(
avctx
,
AV_LOG_DEBUG
,
"rate control: CBR
\n
"
);
av_log
(
avctx
,
AV_LOG_DEBUG
,
" bitrate: %d bps
\n
"
,
avctx
->
bit_rate
);
}
av_log
(
avctx
,
AV_LOG_DEBUG
,
"complexity: %d
\n
"
,
avctx
->
compression_level
);
av_log
(
avctx
,
AV_LOG_DEBUG
,
"frame size: %d samples
\n
"
,
avctx
->
frame_size
);
av_log
(
avctx
,
AV_LOG_DEBUG
,
"frames per packet: %d
\n
"
,
s
->
frames_per_packet
);
av_log
(
avctx
,
AV_LOG_DEBUG
,
"packet size: %d
\n
"
,
avctx
->
frame_size
*
s
->
frames_per_packet
);
}
static
av_cold
int
encode_init
(
AVCodecContext
*
avctx
)
{
LibSpeexEncContext
*
s
=
avctx
->
priv_data
;
const
SpeexMode
*
mode
;
uint8_t
*
header_data
;
int
header_size
;
int32_t
complexity
;
/* channels */
if
(
avctx
->
channels
<
1
||
avctx
->
channels
>
2
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Invalid channels (%d). Only stereo and "
"mono are supported
\n
"
,
avctx
->
channels
);
return
AVERROR
(
EINVAL
);
}
/* sample rate and encoding mode */
switch
(
avctx
->
sample_rate
)
{
case
8000
:
mode
=
&
speex_nb_mode
;
break
;
case
16000
:
mode
=
&
speex_wb_mode
;
break
;
case
32000
:
mode
=
&
speex_uwb_mode
;
break
;
default:
av_log
(
avctx
,
AV_LOG_ERROR
,
"Sample rate of %d Hz is not supported. "
"Resample to 8, 16, or 32 kHz.
\n
"
,
avctx
->
sample_rate
);
return
AVERROR
(
EINVAL
);
}
/* initialize libspeex */
s
->
enc_state
=
speex_encoder_init
(
mode
);
if
(
!
s
->
enc_state
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error initializing libspeex
\n
"
);
return
-
1
;
}
speex_init_header
(
&
s
->
header
,
avctx
->
sample_rate
,
avctx
->
channels
,
mode
);
/* rate control method and parameters */
if
(
avctx
->
flags
&
CODEC_FLAG_QSCALE
)
{
/* VBR */
s
->
header
.
vbr
=
1
;
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_SET_VBR
,
&
s
->
header
.
vbr
);
s
->
vbr_quality
=
av_clipf
(
avctx
->
global_quality
/
(
float
)
FF_QP2LAMBDA
,
0
.
0
f
,
10
.
0
f
);
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_SET_VBR_QUALITY
,
&
s
->
vbr_quality
);
}
else
{
s
->
header
.
bitrate
=
avctx
->
bit_rate
;
if
(
avctx
->
bit_rate
>
0
)
{
/* CBR or ABR by bitrate */
if
(
s
->
abr
)
{
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_SET_ABR
,
&
s
->
header
.
bitrate
);
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_GET_ABR
,
&
s
->
header
.
bitrate
);
}
else
{
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_SET_BITRATE
,
&
s
->
header
.
bitrate
);
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_GET_BITRATE
,
&
s
->
header
.
bitrate
);
}
}
else
{
/* CBR by quality */
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_SET_QUALITY
,
&
s
->
cbr_quality
);
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_GET_BITRATE
,
&
s
->
header
.
bitrate
);
}
/* stereo side information adds about 800 bps to the base bitrate */
/* TODO: this should be calculated exactly */
avctx
->
bit_rate
=
s
->
header
.
bitrate
+
(
avctx
->
channels
==
2
?
800
:
0
);
}
/* set encoding complexity */
if
(
avctx
->
compression_level
>
FF_COMPRESSION_DEFAULT
)
{
complexity
=
av_clip
(
avctx
->
compression_level
,
0
,
10
);
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_SET_COMPLEXITY
,
&
complexity
);
}
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_GET_COMPLEXITY
,
&
complexity
);
avctx
->
compression_level
=
complexity
;
/* set packet size */
avctx
->
frame_size
=
s
->
header
.
frame_size
;
s
->
header
.
frames_per_packet
=
s
->
frames_per_packet
;
/* set encoding delay */
speex_encoder_ctl
(
s
->
enc_state
,
SPEEX_GET_LOOKAHEAD
,
&
s
->
lookahead
);
s
->
sample_count
=
-
s
->
lookahead
;
/* create header packet bytes from header struct */
/* note: libspeex allocates the memory for header_data, which is freed
below with speex_header_free() */
header_data
=
speex_header_to_packet
(
&
s
->
header
,
&
header_size
);
/* allocate extradata and coded_frame */
avctx
->
extradata
=
av_malloc
(
header_size
+
FF_INPUT_BUFFER_PADDING_SIZE
);
avctx
->
coded_frame
=
avcodec_alloc_frame
();
if
(
!
avctx
->
extradata
||
!
avctx
->
coded_frame
)
{
speex_header_free
(
header_data
);
speex_encoder_destroy
(
s
->
enc_state
);
av_log
(
avctx
,
AV_LOG_ERROR
,
"memory allocation error
\n
"
);
return
AVERROR
(
ENOMEM
);
}
/* copy header packet to extradata */
memcpy
(
avctx
->
extradata
,
header_data
,
header_size
);
avctx
->
extradata_size
=
header_size
;
speex_header_free
(
header_data
);
/* init libspeex bitwriter */
speex_bits_init
(
&
s
->
bits
);
print_enc_params
(
avctx
,
s
);
return
0
;
}
static
int
encode_frame
(
AVCodecContext
*
avctx
,
uint8_t
*
frame
,
int
buf_size
,
void
*
data
)
{
LibSpeexEncContext
*
s
=
avctx
->
priv_data
;
int16_t
*
samples
=
data
;
int
sample_count
=
s
->
sample_count
;
if
(
data
)
{
/* encode Speex frame */
if
(
avctx
->
channels
==
2
)
speex_encode_stereo_int
(
samples
,
s
->
header
.
frame_size
,
&
s
->
bits
);
speex_encode_int
(
s
->
enc_state
,
samples
,
&
s
->
bits
);
s
->
pkt_frame_count
++
;
s
->
sample_count
+=
avctx
->
frame_size
;
}
else
{
/* handle end-of-stream */
if
(
!
s
->
pkt_frame_count
)
return
0
;
/* add extra terminator codes for unused frames in last packet */
while
(
s
->
pkt_frame_count
<
s
->
frames_per_packet
)
{
speex_bits_pack
(
&
s
->
bits
,
15
,
5
);
s
->
pkt_frame_count
++
;
}
}
/* write output if all frames for the packet have been encoded */
if
(
s
->
pkt_frame_count
==
s
->
frames_per_packet
)
{
s
->
pkt_frame_count
=
0
;
avctx
->
coded_frame
->
pts
=
av_rescale_q
(
sample_count
,
(
AVRational
){
1
,
avctx
->
sample_rate
},
avctx
->
time_base
);
if
(
buf_size
>
speex_bits_nbytes
(
&
s
->
bits
))
{
int
ret
=
speex_bits_write
(
&
s
->
bits
,
frame
,
buf_size
);
speex_bits_reset
(
&
s
->
bits
);
return
ret
;
}
else
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"output buffer too small"
);
return
AVERROR
(
EINVAL
);
}
}
return
0
;
}
static
av_cold
int
encode_close
(
AVCodecContext
*
avctx
)
{
LibSpeexEncContext
*
s
=
avctx
->
priv_data
;
speex_bits_destroy
(
&
s
->
bits
);
speex_encoder_destroy
(
s
->
enc_state
);
av_freep
(
&
avctx
->
coded_frame
);
av_freep
(
&
avctx
->
extradata
);
return
0
;
}
#define OFFSET(x) offsetof(LibSpeexEncContext, x)
#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static
const
AVOption
options
[]
=
{
{
"abr"
,
"Use average bit rate"
,
OFFSET
(
abr
),
AV_OPT_TYPE_INT
,
{
0
},
0
,
1
,
AE
},
{
"cbr_quality"
,
"Set quality value (0 to 10) for CBR"
,
OFFSET
(
cbr_quality
),
AV_OPT_TYPE_INT
,
{
8
},
0
,
10
,
AE
},
{
"frames_per_packet"
,
"Number of frames to encode in each packet"
,
OFFSET
(
frames_per_packet
),
AV_OPT_TYPE_INT
,
{
1
},
1
,
8
,
AE
},
{
NULL
},
};
static
const
AVClass
class
=
{
.
class_name
=
"libspeex"
,
.
item_name
=
av_default_item_name
,
.
option
=
options
,
.
version
=
LIBAVUTIL_VERSION_INT
,
};
static
const
AVCodecDefault
defaults
[]
=
{
{
"b"
,
"0"
},
{
"compression_level"
,
"3"
},
{
NULL
},
};
AVCodec
ff_libspeex_encoder
=
{
.
name
=
"libspeex"
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
id
=
CODEC_ID_SPEEX
,
.
priv_data_size
=
sizeof
(
LibSpeexEncContext
),
.
init
=
encode_init
,
.
encode
=
encode_frame
,
.
close
=
encode_close
,
.
capabilities
=
CODEC_CAP_DELAY
,
.
sample_fmts
=
(
const
enum
SampleFormat
[]){
AV_SAMPLE_FMT_S16
,
AV_SAMPLE_FMT_NONE
},
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"libspeex Speex"
),
.
priv_class
=
&
class
,
.
defaults
=
defaults
,
};
libavcodec/version.h
View file @
b606a017
...
...
@@ -21,7 +21,7 @@
#define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 53
#define LIBAVCODEC_VERSION_MINOR 1
3
#define LIBAVCODEC_VERSION_MINOR 1
4
#define LIBAVCODEC_VERSION_MICRO 0
#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