Merge remote-tracking branch 'qatar/master'

* qatar/master: (24 commits)
  flvdec: remove incomplete, disabled seeking code
  mem: add support for _aligned_malloc() as found on Windows
  lavc: Extend the documentation for avcodec_init_packet
  flvdec: remove incomplete, disabled seeking code
  http: replace atoll() with strtoll()
  mpegts: remove unused/incomplete/broken seeking code
  af_amix: allow float planar sample format as input
  af_amix: use AVFloatDSPContext.vector_fmac_scalar()
  float_dsp: add x86-optimized functions for vector_fmac_scalar()
  float_dsp: Move vector_fmac_scalar() from libavcodec to libavutil
  lavr: Add x86-optimized function for flt to s32 conversion
  lavr: Add x86-optimized function for flt to s16 conversion
  lavr: Add x86-optimized functions for s32 to flt conversion
  lavr: Add x86-optimized functions for s32 to s16 conversion
  lavr: Add x86-optimized functions for s16 to flt conversion
  lavr: Add x86-optimized function for s16 to s32 conversion
  rtpenc: Support packetizing iLBC
  rtpdec: Add a depacketizer for iLBC
  Implement the iLBC storage file format
  mov: Support muxing/demuxing iLBC
  ...

Conflicts:
	Changelog
	configure
	libavcodec/avcodec.h
	libavcodec/dsputil.c
	libavcodec/version.h
	libavformat/movenc.c
	libavformat/mpegts.c
	libavformat/version.h
	libavutil/mem.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2012-06-19 20:52:00 +02:00
commit cabbd271a5
44 changed files with 952 additions and 231 deletions

View File

@ -10,6 +10,7 @@ version next:
- atempo filter - atempo filter
- ffprobe -show_data option - ffprobe -show_data option
- RTMPT protocol support - RTMPT protocol support
- iLBC encoding/decoding via libilbc
version 0.11: version 0.11:

10
configure vendored
View File

@ -180,6 +180,7 @@ External library support:
--enable-libfaac enable FAAC support via libfaac [no] --enable-libfaac enable FAAC support via libfaac [no]
--enable-libfreetype enable libfreetype [no] --enable-libfreetype enable libfreetype [no]
--enable-libgsm enable GSM support via libgsm [no] --enable-libgsm enable GSM support via libgsm [no]
--enable-libilbc enable iLBC de/encoding via libilbc [no]
--enable-libmodplug enable ModPlug via libmodplug [no] --enable-libmodplug enable ModPlug via libmodplug [no]
--enable-libmp3lame enable MP3 encoding via libmp3lame [no] --enable-libmp3lame enable MP3 encoding via libmp3lame [no]
--enable-libnut enable NUT (de)muxing via libnut, --enable-libnut enable NUT (de)muxing via libnut,
@ -1051,6 +1052,7 @@ CONFIG_LIST="
libfaac libfaac
libfreetype libfreetype
libgsm libgsm
libilbc
libmodplug libmodplug
libmp3lame libmp3lame
libnut libnut
@ -1168,6 +1170,7 @@ HAVE_LIST="
$ARCH_EXT_LIST $ARCH_EXT_LIST
$HAVE_LIST_PUB $HAVE_LIST_PUB
$THREADS_LIST $THREADS_LIST
aligned_malloc
aligned_stack aligned_stack
alsa_asoundlib_h alsa_asoundlib_h
altivec_h altivec_h
@ -1588,6 +1591,8 @@ libgsm_decoder_deps="libgsm"
libgsm_encoder_deps="libgsm" libgsm_encoder_deps="libgsm"
libgsm_ms_decoder_deps="libgsm" libgsm_ms_decoder_deps="libgsm"
libgsm_ms_encoder_deps="libgsm" libgsm_ms_encoder_deps="libgsm"
libilbc_decoder_deps="libilbc"
libilbc_encoder_deps="libilbc"
libmodplug_demuxer_deps="libmodplug" libmodplug_demuxer_deps="libmodplug"
libmp3lame_encoder_deps="libmp3lame" libmp3lame_encoder_deps="libmp3lame"
libopencore_amrnb_decoder_deps="libopencore_amrnb" libopencore_amrnb_decoder_deps="libopencore_amrnb"
@ -3144,6 +3149,7 @@ check_func ${malloc_prefix}memalign && enable memalign
check_func mkstemp check_func mkstemp
check_func mmap check_func mmap
check_func ${malloc_prefix}posix_memalign && enable posix_memalign check_func ${malloc_prefix}posix_memalign && enable posix_memalign
check_func_headers malloc.h _aligned_malloc && enable aligned_malloc
check_func setrlimit check_func setrlimit
check_func strerror_r check_func strerror_r
check_func strptime check_func strptime
@ -3254,6 +3260,7 @@ enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType
enabled libgsm && require libgsm gsm/gsm.h gsm_create -lgsm enabled libgsm && require libgsm gsm/gsm.h gsm_create -lgsm
enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
enabled libmodplug && require libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug enabled libmodplug && require libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug
enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
enabled libnut && require libnut libnut.h nut_demuxer_init -lnut enabled libnut && require libnut libnut.h nut_demuxer_init -lnut
@ -3522,7 +3529,7 @@ if test $target_os = "haiku"; then
disable posix_memalign disable posix_memalign
fi fi
! enabled_any memalign posix_memalign && ! enabled_any memalign posix_memalign aligned_malloc &&
enabled_any $need_memalign && enable memalign_hack enabled_any $need_memalign && enable memalign_hack
# add_dep lib dep # add_dep lib dep
@ -3628,6 +3635,7 @@ echo "libcelt enabled ${libcelt-no}"
echo "libdc1394 support ${libdc1394-no}" echo "libdc1394 support ${libdc1394-no}"
echo "libfaac enabled ${libfaac-no}" echo "libfaac enabled ${libfaac-no}"
echo "libgsm enabled ${libgsm-no}" echo "libgsm enabled ${libgsm-no}"
echo "libilbc enabled ${libilbc-no}"
echo "libmodplug enabled ${libmodplug-no}" echo "libmodplug enabled ${libmodplug-no}"
echo "libmp3lame enabled ${libmp3lame-no}" echo "libmp3lame enabled ${libmp3lame-no}"
echo "libnut enabled ${libnut-no}" echo "libnut enabled ${libnut-no}"

View File

@ -93,6 +93,17 @@ x264 is under the GNU Public License Version 2 or later
details), you must upgrade FFmpeg's license to GPL in order to use it. details), you must upgrade FFmpeg's license to GPL in order to use it.
@end float @end float
@section libilbc
iLBC is a narrowband speech codec that has been made freely available
by Google as part of the WebRTC project. libilbc is a packaging friendly
copy of the iLBC codec. Libav can make use of the libilbc library for
iLBC encoding and decoding.
Go to @url{https://github.com/dekkers/libilbc} and follow the instructions for
installing the library. Then pass @code{--enable-libilbc} to configure to
enable it.
@chapter Supported File Formats, Codecs or Features @chapter Supported File Formats, Codecs or Features
@ -191,6 +202,7 @@ library:
@item IEC61937 encapsulation @tab X @tab X @item IEC61937 encapsulation @tab X @tab X
@item IFF @tab @tab X @item IFF @tab @tab X
@tab Interchange File Format @tab Interchange File Format
@item iLBC @tab X @tab X
@item Interplay MVE @tab @tab X @item Interplay MVE @tab @tab X
@tab Format used in various Interplay computer games. @tab Format used in various Interplay computer games.
@item IV8 @tab @tab X @item IV8 @tab @tab X
@ -749,6 +761,8 @@ following image formats are supported:
@item GSM Microsoft variant @tab E @tab X @item GSM Microsoft variant @tab E @tab X
@tab encoding supported through external library libgsm @tab encoding supported through external library libgsm
@item IAC (Indeo Audio Coder) @tab @tab X @item IAC (Indeo Audio Coder) @tab @tab X
@item iLBC (Internet Low Bitrate Codec) @tab E @tab E
@tab encoding and decoding supported through external library libilbc
@item IMC (Intel Music Coder) @tab @tab X @item IMC (Intel Music Coder) @tab @tab X
@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X @item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X
@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X @item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X

View File

@ -247,6 +247,10 @@ times to construct arbitrary AMF sequences.
Version of the Flash plugin used to run the SWF player. The default Version of the Flash plugin used to run the SWF player. The default
is LNX 9,0,124,2. is LNX 9,0,124,2.
@item rtmp_flush_interval
Number of packets flushed in the same request (RTMPT only). The default
is 10.
@item rtmp_live @item rtmp_live
Specify that the media is a live stream. No resuming or seeking in Specify that the media is a live stream. No resuming or seeking in
live streams is possible. The default value is @code{any}, which means the live streams is possible. The default value is @code{any}, which means the

View File

@ -659,6 +659,8 @@ OBJS-$(CONFIG_LIBGSM_DECODER) += libgsm.o
OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsm.o
OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsm.o
OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsm.o
OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o
OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o
OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o mpegaudiodecheader.o \ OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o mpegaudiodecheader.o \
audio_frame_queue.o audio_frame_queue.o
OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o \ OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o \

View File

@ -410,6 +410,7 @@ void avcodec_register_all(void)
REGISTER_ENCODER (LIBFAAC, libfaac); REGISTER_ENCODER (LIBFAAC, libfaac);
REGISTER_ENCDEC (LIBGSM, libgsm); REGISTER_ENCDEC (LIBGSM, libgsm);
REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms);
REGISTER_ENCDEC (LIBILBC, libilbc);
REGISTER_ENCODER (LIBMP3LAME, libmp3lame); REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb); REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb);
REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb); REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb);

View File

@ -154,8 +154,6 @@ void ff_vector_fmul_window_neon(float *dst, const float *src0,
const float *src1, const float *win, int len); const float *src1, const float *win, int len);
void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul,
int len); int len);
void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul,
int len);
void ff_butterflies_float_neon(float *v1, float *v2, int len); void ff_butterflies_float_neon(float *v1, float *v2, int len);
float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
void ff_vector_fmul_reverse_neon(float *dst, const float *src0, void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
@ -329,7 +327,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
c->vector_fmul_window = ff_vector_fmul_window_neon; c->vector_fmul_window = ff_vector_fmul_window_neon;
c->vector_fmul_scalar = ff_vector_fmul_scalar_neon; c->vector_fmul_scalar = ff_vector_fmul_scalar_neon;
c->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
c->butterflies_float = ff_butterflies_float_neon; c->butterflies_float = ff_butterflies_float_neon;
c->scalarproduct_float = ff_scalarproduct_float_neon; c->scalarproduct_float = ff_scalarproduct_float_neon;
c->vector_fmul_reverse = ff_vector_fmul_reverse_neon; c->vector_fmul_reverse = ff_vector_fmul_reverse_neon;

View File

@ -682,54 +682,6 @@ NOVFP vdup.32 q8, r2
.unreq len .unreq len
endfunc endfunc
function ff_vector_fmac_scalar_neon, export=1
VFP len .req r2
VFP acc .req r3
NOVFP len .req r3
NOVFP acc .req r2
VFP vdup.32 q15, d0[0]
NOVFP vdup.32 q15, r2
bics r12, len, #15
mov acc, r0
beq 3f
vld1.32 {q0}, [r1,:128]!
vld1.32 {q8}, [acc,:128]!
vld1.32 {q1}, [r1,:128]!
vld1.32 {q9}, [acc,:128]!
1: vmla.f32 q8, q0, q15
vld1.32 {q2}, [r1,:128]!
vld1.32 {q10}, [acc,:128]!
vmla.f32 q9, q1, q15
vld1.32 {q3}, [r1,:128]!
vld1.32 {q11}, [acc,:128]!
vmla.f32 q10, q2, q15
vst1.32 {q8}, [r0,:128]!
vmla.f32 q11, q3, q15
vst1.32 {q9}, [r0,:128]!
subs r12, r12, #16
beq 2f
vld1.32 {q0}, [r1,:128]!
vld1.32 {q8}, [acc,:128]!
vst1.32 {q10}, [r0,:128]!
vld1.32 {q1}, [r1,:128]!
vld1.32 {q9}, [acc,:128]!
vst1.32 {q11}, [r0,:128]!
b 1b
2: vst1.32 {q10}, [r0,:128]!
vst1.32 {q11}, [r0,:128]!
ands len, len, #15
it eq
bxeq lr
3: vld1.32 {q0}, [r1,:128]!
vld1.32 {q8}, [acc,:128]!
vmla.f32 q8, q0, q15
vst1.32 {q8}, [r0,:128]!
subs len, len, #4
bgt 3b
bx lr
.unreq len
endfunc
function ff_butterflies_float_neon, export=1 function ff_butterflies_float_neon, export=1
1: vld1.32 {q0},[r0,:128] 1: vld1.32 {q0},[r0,:128]
vld1.32 {q1},[r1,:128] vld1.32 {q1},[r1,:128]

View File

@ -407,6 +407,7 @@ enum CodecID {
CODEC_ID_BMV_AUDIO, CODEC_ID_BMV_AUDIO,
CODEC_ID_RALF, CODEC_ID_RALF,
CODEC_ID_IAC, CODEC_ID_IAC,
CODEC_ID_ILBC,
CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'), CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
CODEC_ID_8SVX_RAW = MKBETAG('8','S','V','X'), CODEC_ID_8SVX_RAW = MKBETAG('8','S','V','X'),
CODEC_ID_SONIC = MKBETAG('S','O','N','C'), CODEC_ID_SONIC = MKBETAG('S','O','N','C'),
@ -3470,6 +3471,9 @@ void av_destruct_packet(AVPacket *pkt);
/** /**
* Initialize optional fields of a packet with default values. * Initialize optional fields of a packet with default values.
* *
* Note, this does not touch the data and size members, which have to be
* initialized separately.
*
* @param pkt packet * @param pkt packet
*/ */
void av_init_packet(AVPacket *pkt); void av_init_packet(AVPacket *pkt);

View File

@ -27,6 +27,7 @@
#include <stdio.h> #include <stdio.h>
#include "libavutil/common.h" #include "libavutil/common.h"
#include "libavutil/float_dsp.h"
#include "libavutil/intmath.h" #include "libavutil/intmath.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h" #include "libavutil/mathematics.h"
@ -384,7 +385,7 @@ typedef struct {
int profile; int profile;
int debug_flag; ///< used for suppressing repeated error messages output int debug_flag; ///< used for suppressing repeated error messages output
DSPContext dsp; AVFloatDSPContext fdsp;
FFTContext imdct; FFTContext imdct;
SynthFilterContext synth; SynthFilterContext synth;
DCADSPContext dcadsp; DCADSPContext dcadsp;
@ -2042,8 +2043,8 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
float *back_chan = s->samples + s->channel_order_tab[s->xch_base_channel] * 256; float *back_chan = s->samples + s->channel_order_tab[s->xch_base_channel] * 256;
float *lt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256; float *lt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256;
float *rt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256; float *rt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256;
s->dsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256); s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
s->dsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256); s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
} }
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
@ -2085,7 +2086,7 @@ static av_cold int dca_decode_init(AVCodecContext *avctx)
s->avctx = avctx; s->avctx = avctx;
dca_init_vlcs(); dca_init_vlcs();
ff_dsputil_init(&s->dsp, avctx); avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
ff_mdct_init(&s->imdct, 6, 1, 1.0); ff_mdct_init(&s->imdct, 6, 1, 1.0);
ff_synth_filter_init(&s->synth); ff_synth_filter_init(&s->synth);
ff_dcadsp_init(&s->dcadsp); ff_dcadsp_init(&s->dcadsp);

View File

@ -127,7 +127,7 @@ static const enum PixelFormat dirac_pix_fmt[2][3] = {
static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,
dirac_source_params *source) dirac_source_params *source)
{ {
AVRational frame_rate = (AVRational){0,0}; AVRational frame_rate = {0,0};
unsigned luma_depth = 8, luma_offset = 16; unsigned luma_depth = 8, luma_offset = 16;
int idx; int idx;

View File

@ -2509,14 +2509,6 @@ static void vector_fmul_scalar_c(float *dst, const float *src, float mul,
dst[i] = src[i] * mul; dst[i] = src[i] * mul;
} }
static void vector_fmac_scalar_c(float *dst, const float *src, float mul,
int len)
{
int i;
for (i = 0; i < len; i++)
dst[i] += src[i] * mul;
}
static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2, static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2,
int len) int len)
{ {
@ -3060,7 +3052,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
c->butterflies_float = butterflies_float_c; c->butterflies_float = butterflies_float_c;
c->butterflies_float_interleave = butterflies_float_interleave_c; c->butterflies_float_interleave = butterflies_float_interleave_c;
c->vector_fmul_scalar = vector_fmul_scalar_c; c->vector_fmul_scalar = vector_fmul_scalar_c;
c->vector_fmac_scalar = vector_fmac_scalar_c;
c->shrink[0]= av_image_copy_plane; c->shrink[0]= av_image_copy_plane;
c->shrink[1]= ff_shrink22; c->shrink[1]= ff_shrink22;

View File

@ -420,17 +420,6 @@ typedef struct DSPContext {
*/ */
void (*vector_fmul_scalar)(float *dst, const float *src, float mul, void (*vector_fmul_scalar)(float *dst, const float *src, float mul,
int len); int len);
/**
* Multiply a vector of floats by a scalar float and add to
* destination vector. Source and destination vectors must
* overlap exactly or not at all.
* @param dst result vector, 16-byte aligned
* @param src input vector, 16-byte aligned
* @param mul scalar value
* @param len length of vector, multiple of 4
*/
void (*vector_fmac_scalar)(float *dst, const float *src, float mul,
int len);
/** /**
* Calculate the scalar product of two vectors of floats. * Calculate the scalar product of two vectors of floats.
* @param v1 first vector, 16-byte aligned * @param v1 first vector, 16-byte aligned

209
libavcodec/libilbc.c Normal file
View File

@ -0,0 +1,209 @@
/*
* iLBC decoder/encoder stub
* Copyright (c) 2012 Martin Storsjo
*
* 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 <ilbc.h>
#include "avcodec.h"
#include "libavutil/opt.h"
#include "internal.h"
static int get_mode(AVCodecContext *avctx)
{
if (avctx->block_align == 38)
return 20;
else if (avctx->block_align == 50)
return 30;
else if (avctx->bit_rate > 0)
return avctx->bit_rate <= 14000 ? 30 : 20;
else
return -1;
}
typedef struct ILBCDecContext {
const AVClass *class;
AVFrame frame;
iLBC_Dec_Inst_t decoder;
int enhance;
} ILBCDecContext;
static const AVOption ilbc_dec_options[] = {
{ "enhance", "Enhance the decoded audio (adds delay)", offsetof(ILBCDecContext, enhance), AV_OPT_TYPE_INT, { 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM },
{ NULL }
};
static const AVClass ilbc_dec_class = {
"libilbc", av_default_item_name, ilbc_dec_options, LIBAVUTIL_VERSION_INT
};
static av_cold int ilbc_decode_init(AVCodecContext *avctx)
{
ILBCDecContext *s = avctx->priv_data;
int mode;
if ((mode = get_mode(avctx)) < 0) {
av_log(avctx, AV_LOG_ERROR, "iLBC frame mode not indicated\n");
return AVERROR(EINVAL);
}
WebRtcIlbcfix_InitDecode(&s->decoder, mode, s->enhance);
avcodec_get_frame_defaults(&s->frame);
avctx->coded_frame = &s->frame;
avctx->channels = 1;
avctx->sample_rate = 8000;
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
return 0;
}
static int ilbc_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
ILBCDecContext *s = avctx->priv_data;
int ret;
if (s->decoder.no_of_bytes > buf_size) {
av_log(avctx, AV_LOG_ERROR, "iLBC frame too short (%u, should be %u)\n",
buf_size, s->decoder.no_of_bytes);
return AVERROR_INVALIDDATA;
}
s->frame.nb_samples = s->decoder.blockl;
if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return ret;
}
WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) s->frame.data[0],
(const WebRtc_UWord16*) buf, &s->decoder, 1);
*got_frame_ptr = 1;
*(AVFrame *)data = s->frame;
return s->decoder.no_of_bytes;
}
AVCodec ff_libilbc_decoder = {
.name = "libilbc",
.type = AVMEDIA_TYPE_AUDIO,
.id = CODEC_ID_ILBC,
.priv_data_size = sizeof(ILBCDecContext),
.init = ilbc_decode_init,
.decode = ilbc_decode_frame,
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Internet Low Bitrate Codec (iLBC)"),
.priv_class = &ilbc_dec_class,
};
typedef struct ILBCEncContext {
const AVClass *class;
iLBC_Enc_Inst_t encoder;
int mode;
} ILBCEncContext;
static const AVOption ilbc_enc_options[] = {
{ "mode", "iLBC mode (20 or 30 ms frames)", offsetof(ILBCEncContext, mode), AV_OPT_TYPE_INT, { 20 }, 20, 30, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
{ NULL }
};
static const AVClass ilbc_enc_class = {
"libilbc", av_default_item_name, ilbc_enc_options, LIBAVUTIL_VERSION_INT
};
static av_cold int ilbc_encode_init(AVCodecContext *avctx)
{
ILBCEncContext *s = avctx->priv_data;
int mode;
if (avctx->sample_rate != 8000) {
av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
return AVERROR(EINVAL);
}
if (avctx->channels != 1) {
av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
return AVERROR(EINVAL);
}
if ((mode = get_mode(avctx)) > 0)
s->mode = mode;
else
s->mode = s->mode != 30 ? 20 : 30;
WebRtcIlbcfix_InitEncode(&s->encoder, s->mode);
avctx->block_align = s->encoder.no_of_bytes;
avctx->frame_size = s->encoder.blockl;
#if FF_API_OLD_ENCODE_AUDIO
avctx->coded_frame = avcodec_alloc_frame();
if (!avctx->coded_frame)
return AVERROR(ENOMEM);
#endif
return 0;
}
static av_cold int ilbc_encode_close(AVCodecContext *avctx)
{
#if FF_API_OLD_ENCODE_AUDIO
av_freep(&avctx->coded_frame);
#endif
return 0;
}
static int ilbc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const AVFrame *frame, int *got_packet_ptr)
{
ILBCEncContext *s = avctx->priv_data;
int ret;
if ((ret = ff_alloc_packet(avpkt, 50))) {
av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
return ret;
}
WebRtcIlbcfix_EncodeImpl((WebRtc_UWord16*) avpkt->data, (const WebRtc_Word16*) frame->data[0], &s->encoder);
avpkt->size = s->encoder.no_of_bytes;
*got_packet_ptr = 1;
return 0;
}
static const AVCodecDefault ilbc_encode_defaults[] = {
{ "b", "0" },
{ NULL }
};
AVCodec ff_libilbc_encoder = {
.name = "libilbc",
.type = AVMEDIA_TYPE_AUDIO,
.id = CODEC_ID_ILBC,
.priv_data_size = sizeof(ILBCEncContext),
.init = ilbc_encode_init,
.encode2 = ilbc_encode_frame,
.close = ilbc_encode_close,
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("Internet Low Bitrate Codec (iLBC)"),
.defaults = ilbc_encode_defaults,
.priv_class = &ilbc_enc_class,
};

View File

@ -514,14 +514,6 @@ static double predict_size(Predictor *p, double q, double var)
return p->coeff*var / (q*p->count); return p->coeff*var / (q*p->count);
} }
/*
static double predict_qp(Predictor *p, double size, double var)
{
//printf("coeff:%f, count:%f, var:%f, size:%f//\n", p->coeff, p->count, var, size);
return p->coeff*var / (size*p->count);
}
*/
static void update_predictor(Predictor *p, double q, double var, double size) static void update_predictor(Predictor *p, double q, double var, double size)
{ {
double new_coeff= size*q / (var + 1); double new_coeff= size*q / (var + 1);
@ -561,10 +553,6 @@ static void adaptive_quantization(MpegEncContext *s, double q){
int mb_y = mb_xy / s->mb_stride; int mb_y = mb_xy / s->mb_stride;
int mb_distance; int mb_distance;
float mb_factor = 0.0; float mb_factor = 0.0;
#if 0
if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune
if(temp_cplx < q/3) temp_cplx= q/3; //FIXME finetune
#endif
if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune
if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune

View File

@ -2138,6 +2138,11 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
case 29: return 288; case 29: return 288;
case 37: return 480; case 37: return 480;
} }
} else if (id == CODEC_ID_ILBC) {
switch (ba) {
case 38: return 160;
case 50: return 240;
}
} }
} }

View File

@ -27,7 +27,7 @@
*/ */
#define LIBAVCODEC_VERSION_MAJOR 54 #define LIBAVCODEC_VERSION_MAJOR 54
#define LIBAVCODEC_VERSION_MINOR 25 #define LIBAVCODEC_VERSION_MINOR 26
#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \

View File

@ -32,6 +32,7 @@
#include "libavutil/audio_fifo.h" #include "libavutil/audio_fifo.h"
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/float_dsp.h"
#include "libavutil/mathematics.h" #include "libavutil/mathematics.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/samplefmt.h" #include "libavutil/samplefmt.h"
@ -152,6 +153,7 @@ static int frame_list_add_frame(FrameList *frame_list, int nb_samples, int64_t p
typedef struct MixContext { typedef struct MixContext {
const AVClass *class; /**< class for AVOptions */ const AVClass *class; /**< class for AVOptions */
AVFloatDSPContext fdsp;
int nb_inputs; /**< number of inputs */ int nb_inputs; /**< number of inputs */
int active_inputs; /**< number of input currently active */ int active_inputs; /**< number of input currently active */
@ -160,6 +162,7 @@ typedef struct MixContext {
int nb_channels; /**< number of channels */ int nb_channels; /**< number of channels */
int sample_rate; /**< sample rate */ int sample_rate; /**< sample rate */
int planar;
AVAudioFifo **fifos; /**< audio fifo for each input */ AVAudioFifo **fifos; /**< audio fifo for each input */
uint8_t *input_state; /**< current state of each input */ uint8_t *input_state; /**< current state of each input */
float *input_scale; /**< mixing scale factor for each input */ float *input_scale; /**< mixing scale factor for each input */
@ -224,6 +227,7 @@ static int config_output(AVFilterLink *outlink)
int i; int i;
char buf[64]; char buf[64];
s->planar = av_sample_fmt_is_planar(outlink->format);
s->sample_rate = outlink->sample_rate; s->sample_rate = outlink->sample_rate;
outlink->time_base = (AVRational){ 1, outlink->sample_rate }; outlink->time_base = (AVRational){ 1, outlink->sample_rate };
s->next_pts = AV_NOPTS_VALUE; s->next_pts = AV_NOPTS_VALUE;
@ -264,14 +268,6 @@ static int config_output(AVFilterLink *outlink)
return 0; return 0;
} }
/* TODO: move optimized version from DSPContext to libavutil */
static void vector_fmac_scalar(float *dst, const float *src, float mul, int len)
{
int i;
for (i = 0; i < len; i++)
dst[i] += src[i] * mul;
}
/** /**
* Read samples from the input FIFOs, mix, and write to the output link. * Read samples from the input FIFOs, mix, and write to the output link.
*/ */
@ -294,11 +290,20 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
for (i = 0; i < s->nb_inputs; i++) { for (i = 0; i < s->nb_inputs; i++) {
if (s->input_state[i] == INPUT_ON) { if (s->input_state[i] == INPUT_ON) {
int planes, plane_size, p;
av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data, av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data,
nb_samples); nb_samples);
vector_fmac_scalar((float *)out_buf->extended_data[0],
(float *) in_buf->extended_data[0], planes = s->planar ? s->nb_channels : 1;
s->input_scale[i], nb_samples * s->nb_channels); plane_size = nb_samples * (s->planar ? 1 : s->nb_channels);
plane_size = FFALIGN(plane_size, 16);
for (p = 0; p < planes; p++) {
s->fdsp.vector_fmac_scalar((float *)out_buf->extended_data[p],
(float *) in_buf->extended_data[p],
s->input_scale[i], plane_size);
}
} }
} }
avfilter_unref_buffer(in_buf); avfilter_unref_buffer(in_buf);
@ -501,6 +506,8 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque)
ff_insert_inpad(ctx, i, &pad); ff_insert_inpad(ctx, i, &pad);
} }
avpriv_float_dsp_init(&s->fdsp, 0);
return 0; return 0;
} }
@ -527,6 +534,7 @@ static int query_formats(AVFilterContext *ctx)
{ {
AVFilterFormats *formats = NULL; AVFilterFormats *formats = NULL;
ff_add_format(&formats, AV_SAMPLE_FMT_FLT); ff_add_format(&formats, AV_SAMPLE_FMT_FLT);
ff_add_format(&formats, AV_SAMPLE_FMT_FLTP);
ff_set_common_formats(ctx, formats); ff_set_common_formats(ctx, formats);
ff_set_common_channel_layouts(ctx, ff_all_channel_layouts()); ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
ff_set_common_samplerates(ctx, ff_all_samplerates()); ff_set_common_samplerates(ctx, ff_all_samplerates());

View File

@ -123,6 +123,8 @@ OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o
OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o
OBJS-$(CONFIG_IDF_DEMUXER) += bintext.o OBJS-$(CONFIG_IDF_DEMUXER) += bintext.o
OBJS-$(CONFIG_IFF_DEMUXER) += iff.o OBJS-$(CONFIG_IFF_DEMUXER) += iff.o
OBJS-$(CONFIG_ILBC_DEMUXER) += ilbc.o
OBJS-$(CONFIG_ILBC_MUXER) += ilbc.o
OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2dec.o img2.o
OBJS-$(CONFIG_IMAGE2_MUXER) += img2enc.o img2.o OBJS-$(CONFIG_IMAGE2_MUXER) += img2enc.o img2.o
OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER) += img2dec.o img2.o
@ -281,6 +283,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \
rtpdec_h263.o \ rtpdec_h263.o \
rtpdec_h263_rfc2190.o \ rtpdec_h263_rfc2190.o \
rtpdec_h264.o \ rtpdec_h264.o \
rtpdec_ilbc.o \
rtpdec_latm.o \ rtpdec_latm.o \
rtpdec_mpeg4.o \ rtpdec_mpeg4.o \
rtpdec_qcelp.o \ rtpdec_qcelp.o \

View File

@ -116,6 +116,7 @@ void av_register_all(void)
REGISTER_DEMUXER (IDCIN, idcin); REGISTER_DEMUXER (IDCIN, idcin);
REGISTER_DEMUXER (IDF, idf); REGISTER_DEMUXER (IDF, idf);
REGISTER_DEMUXER (IFF, iff); REGISTER_DEMUXER (IFF, iff);
REGISTER_MUXDEMUX (ILBC, ilbc);
REGISTER_MUXDEMUX (IMAGE2, image2); REGISTER_MUXDEMUX (IMAGE2, image2);
REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe); REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe);
REGISTER_DEMUXER (INGENIENT, ingenient); REGISTER_DEMUXER (INGENIENT, ingenient);

View File

@ -759,33 +759,6 @@ static int flv_read_seek(AVFormatContext *s, int stream_index,
return avio_seek_time(s->pb, stream_index, ts, flags); return avio_seek_time(s->pb, stream_index, ts, flags);
} }
#if 0 /* don't know enough to implement this */
static int flv_read_seek2(AVFormatContext *s, int stream_index,
int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
{
int ret = AVERROR(ENOSYS);
if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD;
if (!s->pb->seekable) {
if (stream_index < 0) {
stream_index = av_find_default_stream_index(s);
if (stream_index < 0)
return -1;
/* timestamp for default must be expressed in AV_TIME_BASE units */
ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE,
flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
}
ret = avio_seek_time(s->pb, stream_index, ts, flags);
}
if (ret == AVERROR(ENOSYS))
ret = av_seek_frame(s, stream_index, ts, flags);
return ret;
}
#endif
AVInputFormat ff_flv_demuxer = { AVInputFormat ff_flv_demuxer = {
.name = "flv", .name = "flv",
.long_name = NULL_IF_CONFIG_SMALL("FLV format"), .long_name = NULL_IF_CONFIG_SMALL("FLV format"),
@ -794,9 +767,6 @@ AVInputFormat ff_flv_demuxer = {
.read_header = flv_read_header, .read_header = flv_read_header,
.read_packet = flv_read_packet, .read_packet = flv_read_packet,
.read_seek = flv_read_seek, .read_seek = flv_read_seek,
#if 0
.read_seek2 = flv_read_seek2,
#endif
.read_close = flv_read_close, .read_close = flv_read_close,
.extensions = "flv", .extensions = "flv",
}; };

View File

@ -308,15 +308,15 @@ static int process_line(URLContext *h, char *line, int line_count,
strcpy(s->location, p); strcpy(s->location, p);
*new_location = 1; *new_location = 1;
} else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) { } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
s->filesize = atoll(p); s->filesize = strtoll(p, NULL, 10);
} else if (!av_strcasecmp (tag, "Content-Range")) { } else if (!av_strcasecmp (tag, "Content-Range")) {
/* "bytes $from-$to/$document_size" */ /* "bytes $from-$to/$document_size" */
const char *slash; const char *slash;
if (!strncmp (p, "bytes ", 6)) { if (!strncmp (p, "bytes ", 6)) {
p += 6; p += 6;
s->off = atoll(p); s->off = strtoll(p, NULL, 10);
if ((slash = strchr(p, '/')) && strlen(slash) > 0) if ((slash = strchr(p, '/')) && strlen(slash) > 0)
s->filesize = atoll(slash+1); s->filesize = strtoll(slash+1, NULL, 10);
} }
h->is_streamed = 0; /* we _can_ in fact seek */ h->is_streamed = 0; /* we _can_ in fact seek */
} else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) { } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {

141
libavformat/ilbc.c Normal file
View File

@ -0,0 +1,141 @@
/*
* iLBC storage file format
* Copyright (c) 2012 Martin Storsjo
*
* 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 "avformat.h"
#include "internal.h"
static const char mode20_header[] = "#!iLBC20\n";
static const char mode30_header[] = "#!iLBC30\n";
static int ilbc_write_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
AVCodecContext *enc;
if (s->nb_streams != 1) {
av_log(s, AV_LOG_ERROR, "Unsupported number of streams\n");
return AVERROR(EINVAL);
}
enc = s->streams[0]->codec;
if (enc->codec_id != CODEC_ID_ILBC) {
av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
return AVERROR(EINVAL);
}
if (enc->block_align == 50) {
avio_write(pb, mode30_header, sizeof(mode30_header) - 1);
} else if (enc->block_align == 38) {
avio_write(pb, mode20_header, sizeof(mode20_header) - 1);
} else {
av_log(s, AV_LOG_ERROR, "Unsupported mode\n");
return AVERROR(EINVAL);
}
avio_flush(pb);
return 0;
}
static int ilbc_write_packet(AVFormatContext *s, AVPacket *pkt)
{
avio_write(s->pb, pkt->data, pkt->size);
avio_flush(s->pb);
return 0;
}
static int ilbc_probe(AVProbeData *p)
{
// Only check for "#!iLBC" which matches both formats
if (!memcmp(p->buf, mode20_header, 6))
return AVPROBE_SCORE_MAX;
else
return 0;
}
static int ilbc_read_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
AVStream *st;
uint8_t header[9];
avio_read(pb, header, 9);
st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
st->codec->codec_id = CODEC_ID_ILBC;
st->codec->sample_rate = 8000;
st->codec->channels = 1;
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->start_time = 0;
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
if (!memcmp(header, mode20_header, sizeof(mode20_header) - 1)) {
st->codec->block_align = 38;
st->codec->bit_rate = 15200;
} else if (!memcmp(header, mode30_header, sizeof(mode30_header) - 1)) {
st->codec->block_align = 50;
st->codec->bit_rate = 13333;
} else {
av_log(s, AV_LOG_ERROR, "Unrecognized iLBC file header\n");
return AVERROR_INVALIDDATA;
}
return 0;
}
static int ilbc_read_packet(AVFormatContext *s,
AVPacket *pkt)
{
AVCodecContext *enc = s->streams[0]->codec;
int ret;
if ((ret = av_new_packet(pkt, enc->block_align)) < 0)
return ret;
pkt->stream_index = 0;
pkt->pos = avio_tell(s->pb);
pkt->duration = enc->block_align == 38 ? 160 : 240;
if ((ret = avio_read(s->pb, pkt->data, enc->block_align)) != enc->block_align) {
av_free_packet(pkt);
return ret < 0 ? ret : AVERROR(EIO);
}
return 0;
}
AVInputFormat ff_ilbc_demuxer = {
.name = "ilbc",
.long_name = NULL_IF_CONFIG_SMALL("iLBC storage file format"),
.read_probe = ilbc_probe,
.read_header = ilbc_read_header,
.read_packet = ilbc_read_packet,
.flags = AVFMT_GENERIC_INDEX,
};
AVOutputFormat ff_ilbc_muxer = {
.name = "ilbc",
.long_name = NULL_IF_CONFIG_SMALL("iLBC storage file format"),
.mime_type = "audio/iLBC",
.extensions = "lbc",
.audio_codec = CODEC_ID_ILBC,
.write_header = ilbc_write_header,
.write_packet = ilbc_write_packet,
.flags = AVFMT_NOTIMESTAMPS,
};

View File

@ -259,6 +259,7 @@ const AVCodecTag ff_codec_movaudio_tags[] = {
{ CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') }, { CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') },
{ CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') }, { CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') },
{ CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') }, { CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') },
{ CODEC_ID_ILBC, MKTAG('i', 'l', 'b', 'c') },
{ CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') },
{ CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') },
{ CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') }, { CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') },

View File

@ -1540,6 +1540,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
case CODEC_ID_GSM: case CODEC_ID_GSM:
case CODEC_ID_ADPCM_MS: case CODEC_ID_ADPCM_MS:
case CODEC_ID_ADPCM_IMA_WAV: case CODEC_ID_ADPCM_IMA_WAV:
case CODEC_ID_ILBC:
st->codec->block_align = sc->bytes_per_frame; st->codec->block_align = sc->bytes_per_frame;
break; break;
case CODEC_ID_ALAC: case CODEC_ID_ALAC:

View File

@ -3371,7 +3371,8 @@ static int mov_write_header(AVFormatContext *s)
av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i); av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
track->audio_vbr = 1; track->audio_vbr = 1;
}else if(st->codec->codec_id == CODEC_ID_ADPCM_MS || }else if(st->codec->codec_id == CODEC_ID_ADPCM_MS ||
st->codec->codec_id == CODEC_ID_ADPCM_IMA_WAV){ st->codec->codec_id == CODEC_ID_ADPCM_IMA_WAV ||
st->codec->codec_id == CODEC_ID_ILBC){
if (!st->codec->block_align) { if (!st->codec->block_align) {
av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i); av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
goto error; goto error;

View File

@ -19,8 +19,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
//#define USE_SYNCPOINT_SEARCH
#include "libavutil/crc.h" #include "libavutil/crc.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "libavutil/log.h" #include "libavutil/log.h"
@ -2161,92 +2159,6 @@ static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index,
return AV_NOPTS_VALUE; return AV_NOPTS_VALUE;
} }
#ifdef USE_SYNCPOINT_SEARCH
static int read_seek2(AVFormatContext *s,
int stream_index,
int64_t min_ts,
int64_t target_ts,
int64_t max_ts,
int flags)
{
int64_t pos;
int64_t ts_ret, ts_adj;
int stream_index_gen_search;
AVStream *st;
AVParserState *backup;
backup = ff_store_parser_state(s);
// detect direction of seeking for search purposes
flags |= (target_ts - min_ts > (uint64_t)(max_ts - target_ts)) ?
AVSEEK_FLAG_BACKWARD : 0;
if (flags & AVSEEK_FLAG_BYTE) {
// use position directly, we will search starting from it
pos = target_ts;
} else {
// search for some position with good timestamp match
if (stream_index < 0) {
stream_index_gen_search = av_find_default_stream_index(s);
if (stream_index_gen_search < 0) {
ff_restore_parser_state(s, backup);
return -1;
}
st = s->streams[stream_index_gen_search];
// timestamp for default must be expressed in AV_TIME_BASE units
ts_adj = av_rescale(target_ts,
st->time_base.den,
AV_TIME_BASE * (int64_t)st->time_base.num);
} else {
ts_adj = target_ts;
stream_index_gen_search = stream_index;
}
pos = ff_gen_search(s, stream_index_gen_search, ts_adj,
0, INT64_MAX, -1,
AV_NOPTS_VALUE,
AV_NOPTS_VALUE,
flags, &ts_ret, mpegts_get_pcr);
if (pos < 0) {
ff_restore_parser_state(s, backup);
return -1;
}
}
// search for actual matching keyframe/starting position for all streams
if (ff_gen_syncpoint_search(s, stream_index, pos,
min_ts, target_ts, max_ts,
flags) < 0) {
ff_restore_parser_state(s, backup);
return -1;
}
ff_free_parser_state(s, backup);
return 0;
}
static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
{
int ret;
if (flags & AVSEEK_FLAG_BACKWARD) {
flags &= ~AVSEEK_FLAG_BACKWARD;
ret = read_seek2(s, stream_index, INT64_MIN, target_ts, target_ts, flags);
if (ret < 0)
// for compatibility reasons, seek to the best-fitting timestamp
ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags);
} else {
ret = read_seek2(s, stream_index, target_ts, target_ts, INT64_MAX, flags);
if (ret < 0)
// for compatibility reasons, seek to the best-fitting timestamp
ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags);
}
return ret;
}
#endif
/**************************************************************/ /**************************************************************/
/* parsing functions - called from other demuxers such as RTP */ /* parsing functions - called from other demuxers such as RTP */
@ -2313,9 +2225,6 @@ AVInputFormat ff_mpegts_demuxer = {
.read_close = mpegts_read_close, .read_close = mpegts_read_close,
.read_timestamp = mpegts_get_dts, .read_timestamp = mpegts_get_dts,
.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
#ifdef USE_SYNCPOINT_SEARCH
.read_seek2 = read_seek2,
#endif
}; };
AVInputFormat ff_mpegtsraw_demuxer = { AVInputFormat ff_mpegtsraw_demuxer = {
@ -2327,8 +2236,5 @@ AVInputFormat ff_mpegtsraw_demuxer = {
.read_close = mpegts_read_close, .read_close = mpegts_read_close,
.read_timestamp = mpegts_get_dts, .read_timestamp = mpegts_get_dts,
.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
#ifdef USE_SYNCPOINT_SEARCH
.read_seek2 = read_seek2,
#endif
.priv_class = &mpegtsraw_class, .priv_class = &mpegtsraw_class,
}; };

View File

@ -76,6 +76,7 @@ typedef struct RTMPContext {
uint8_t* flv_data; ///< buffer with data for demuxer uint8_t* flv_data; ///< buffer with data for demuxer
int flv_size; ///< current buffer size int flv_size; ///< current buffer size
int flv_off; ///< number of bytes read from current buffer int flv_off; ///< number of bytes read from current buffer
int flv_nb_packets; ///< number of flv packets published
RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output) RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output)
uint32_t client_report_size; ///< number of bytes after which client should report to server uint32_t client_report_size; ///< number of bytes after which client should report to server
uint32_t bytes_read; ///< number of bytes read from server uint32_t bytes_read; ///< number of bytes read from server
@ -90,6 +91,7 @@ typedef struct RTMPContext {
char* swfurl; ///< url of the swf player char* swfurl; ///< url of the swf player
int server_bw; ///< server bandwidth int server_bw; ///< server bandwidth
int client_buffer_time; ///< client buffer time in ms int client_buffer_time; ///< client buffer time in ms
int flush_interval; ///< number of packets flushed in the same request (RTMPT only)
} RTMPContext; } RTMPContext;
#define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
@ -1361,9 +1363,14 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
rt->flv_size = 0; rt->flv_size = 0;
rt->flv_off = 0; rt->flv_off = 0;
rt->flv_header_bytes = 0; rt->flv_header_bytes = 0;
rt->flv_nb_packets++;
} }
} while (buf_temp - buf < size); } while (buf_temp - buf < size);
if (rt->flv_nb_packets < rt->flush_interval)
return size;
rt->flv_nb_packets = 0;
/* set stream into nonblocking mode */ /* set stream into nonblocking mode */
rt->stream->flags |= AVIO_FLAG_NONBLOCK; rt->stream->flags |= AVIO_FLAG_NONBLOCK;
@ -1404,6 +1411,7 @@ static const AVOption rtmp_options[] = {
{"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {3000}, 0, INT_MAX, DEC|ENC}, {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {3000}, 0, INT_MAX, DEC|ENC},
{"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
{"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
{"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {10}, 0, INT_MAX, ENC},
{"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"}, {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
{"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"}, {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
{"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"}, {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},

View File

@ -68,6 +68,7 @@ void av_register_rtp_dynamic_payload_handlers(void)
ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler); ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler); ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler); ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler); ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler); ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler); ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);

View File

@ -45,6 +45,7 @@ extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler; extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler; extern RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler;
extern RTPDynamicProtocolHandler ff_h264_dynamic_handler; extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
extern RTPDynamicProtocolHandler ff_ilbc_dynamic_handler;
extern RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler; extern RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler;
extern RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler; extern RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler;
extern RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler; extern RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler;

73
libavformat/rtpdec_ilbc.c Normal file
View File

@ -0,0 +1,73 @@
/*
* RTP iLBC Depacketizer, RFC 3952
* Copyright (c) 2012 Martin Storsjo
*
* 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 "avformat.h"
#include "rtpdec_formats.h"
#include "libavutil/avstring.h"
static int ilbc_parse_fmtp(AVStream *stream, PayloadContext *data,
char *attr, char *value)
{
if (!strcmp(attr, "mode")) {
int mode = atoi(value);
switch (mode) {
case 20:
stream->codec->block_align = 38;
break;
case 30:
stream->codec->block_align = 50;
break;
default:
av_log(NULL, AV_LOG_ERROR, "Unsupported iLBC mode %d\n", mode);
return AVERROR(EINVAL);
}
}
return 0;
}
static int ilbc_parse_sdp_line(AVFormatContext *s, int st_index,
PayloadContext *data, const char *line)
{
const char *p;
AVStream *st;
if (st_index < 0)
return 0;
st = s->streams[st_index];
if (av_strstart(line, "fmtp:", &p)) {
int ret = ff_parse_fmtp(st, data, p, ilbc_parse_fmtp);
if (ret < 0)
return ret;
if (!st->codec->block_align) {
av_log(s, AV_LOG_ERROR, "No iLBC mode set\n");
return AVERROR(EINVAL);
}
}
return 0;
}
RTPDynamicProtocolHandler ff_ilbc_dynamic_handler = {
.enc_name = "iLBC",
.codec_type = AVMEDIA_TYPE_AUDIO,
.codec_id = CODEC_ID_ILBC,
.parse_sdp_a_line = ilbc_parse_sdp_line,
};

View File

@ -74,6 +74,7 @@ static int is_supported(enum CodecID id)
case CODEC_ID_VP8: case CODEC_ID_VP8:
case CODEC_ID_ADPCM_G722: case CODEC_ID_ADPCM_G722:
case CODEC_ID_ADPCM_G726: case CODEC_ID_ADPCM_G726:
case CODEC_ID_ILBC:
return 1; return 1;
default: default:
return 0; return 0;
@ -187,6 +188,16 @@ static int rtp_write_header(AVFormatContext *s1)
* 8000, even if the sample rate is 16000. See RFC 3551. */ * 8000, even if the sample rate is 16000. See RFC 3551. */
avpriv_set_pts_info(st, 32, 1, 8000); avpriv_set_pts_info(st, 32, 1, 8000);
break; break;
case CODEC_ID_ILBC:
if (st->codec->block_align != 38 && st->codec->block_align != 50) {
av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n");
goto fail;
}
if (!s->max_frames_per_packet)
s->max_frames_per_packet = 1;
s->max_frames_per_packet = FFMIN(s->max_frames_per_packet,
s->max_payload_size / st->codec->block_align);
goto defaultcase;
case CODEC_ID_AMR_NB: case CODEC_ID_AMR_NB:
case CODEC_ID_AMR_WB: case CODEC_ID_AMR_WB:
if (!s->max_frames_per_packet) if (!s->max_frames_per_packet)
@ -395,6 +406,36 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1,
} }
} }
static int rtp_send_ilbc(AVFormatContext *s1, const uint8_t *buf, int size)
{
RTPMuxContext *s = s1->priv_data;
AVStream *st = s1->streams[0];
int frame_duration = av_get_audio_frame_duration(st->codec, 0);
int frame_size = st->codec->block_align;
int frames = size / frame_size;
while (frames > 0) {
int n = FFMIN(s->max_frames_per_packet - s->num_frames, frames);
if (!s->num_frames) {
s->buf_ptr = s->buf;
s->timestamp = s->cur_timestamp;
}
memcpy(s->buf_ptr, buf, n * frame_size);
frames -= n;
s->num_frames += n;
s->buf_ptr += n * frame_size;
buf += n * frame_size;
s->cur_timestamp += n * frame_duration;
if (s->num_frames == s->max_frames_per_packet) {
ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 1);
s->num_frames = 0;
}
}
return 0;
}
static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
{ {
RTPMuxContext *s = s1->priv_data; RTPMuxContext *s = s1->priv_data;
@ -483,6 +524,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
case CODEC_ID_VP8: case CODEC_ID_VP8:
ff_rtp_send_vp8(s1, pkt->data, size); ff_rtp_send_vp8(s1, pkt->data, size);
break; break;
case CODEC_ID_ILBC:
rtp_send_ilbc(s1, pkt->data, size);
break;
default: default:
/* better than nothing : send the codec raw data */ /* better than nothing : send the codec raw data */
rtp_send_raw(s1, pkt->data, size); rtp_send_raw(s1, pkt->data, size);

View File

@ -1279,7 +1279,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
"%s/UDP;multicast", trans_pref); "%s/UDP;multicast", trans_pref);
} }
if (s->oformat) { if (s->oformat) {
av_strlcat(transport, ";mode=receive", sizeof(transport)); av_strlcat(transport, ";mode=record", sizeof(transport));
} else if (rt->server_type == RTSP_SERVER_REAL || } else if (rt->server_type == RTSP_SERVER_REAL ||
rt->server_type == RTSP_SERVER_WMS) rt->server_type == RTSP_SERVER_WMS)
av_strlcat(transport, ";mode=play", sizeof(transport)); av_strlcat(transport, ";mode=play", sizeof(transport));

View File

@ -549,6 +549,12 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
c->sample_rate); c->sample_rate);
break; break;
} }
case CODEC_ID_ILBC:
av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n"
"a=fmtp:%d mode=%d\r\n",
payload_type, c->sample_rate,
payload_type, c->block_align == 38 ? 20 : 30);
break;
default: default:
/* Nothing special to do here... */ /* Nothing special to do here... */
break; break;

View File

@ -30,7 +30,7 @@
#include "libavutil/avutil.h" #include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MAJOR 54
#define LIBAVFORMAT_VERSION_MINOR 8 #define LIBAVFORMAT_VERSION_MINOR 9
#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \

View File

@ -1,6 +1,7 @@
;****************************************************************************** ;******************************************************************************
;* x86 optimized Format Conversion Utils ;* x86 optimized Format Conversion Utils
;* Copyright (c) 2008 Loren Merritt ;* Copyright (c) 2008 Loren Merritt
;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
;* ;*
;* This file is part of Libav. ;* This file is part of Libav.
;* ;*
@ -21,9 +22,217 @@
%include "x86inc.asm" %include "x86inc.asm"
%include "x86util.asm" %include "x86util.asm"
%include "util.asm"
SECTION_RODATA 32
pf_s32_inv_scale: times 8 dd 0x30000000
pf_s32_scale: times 8 dd 0x4f000000
pf_s16_inv_scale: times 4 dd 0x38000000
pf_s16_scale: times 4 dd 0x47000000
SECTION_TEXT SECTION_TEXT
;------------------------------------------------------------------------------
; void ff_conv_s16_to_s32(int32_t *dst, const int16_t *src, int len);
;------------------------------------------------------------------------------
INIT_XMM sse2
cglobal conv_s16_to_s32, 3,3,3, dst, src, len
lea lenq, [2*lend]
lea dstq, [dstq+2*lenq]
add srcq, lenq
neg lenq
.loop:
mova m2, [srcq+lenq]
pxor m0, m0
pxor m1, m1
punpcklwd m0, m2
punpckhwd m1, m2
mova [dstq+2*lenq ], m0
mova [dstq+2*lenq+mmsize], m1
add lenq, mmsize
jl .loop
REP_RET
;------------------------------------------------------------------------------
; void ff_conv_s16_to_flt(float *dst, const int16_t *src, int len);
;------------------------------------------------------------------------------
%macro CONV_S16_TO_FLT 0
cglobal conv_s16_to_flt, 3,3,3, dst, src, len
lea lenq, [2*lend]
add srcq, lenq
lea dstq, [dstq + 2*lenq]
neg lenq
mova m2, [pf_s16_inv_scale]
ALIGN 16
.loop:
mova m0, [srcq+lenq]
S16_TO_S32_SX 0, 1
cvtdq2ps m0, m0
cvtdq2ps m1, m1
mulps m0, m2
mulps m1, m2
mova [dstq+2*lenq ], m0
mova [dstq+2*lenq+mmsize], m1
add lenq, mmsize
jl .loop
REP_RET
%endmacro
INIT_XMM sse2
CONV_S16_TO_FLT
INIT_XMM sse4
CONV_S16_TO_FLT
;------------------------------------------------------------------------------
; void ff_conv_s32_to_s16(int16_t *dst, const int32_t *src, int len);
;------------------------------------------------------------------------------
%macro CONV_S32_TO_S16 0
cglobal conv_s32_to_s16, 3,3,4, dst, src, len
lea lenq, [2*lend]
lea srcq, [srcq+2*lenq]
add dstq, lenq
neg lenq
.loop:
mova m0, [srcq+2*lenq ]
mova m1, [srcq+2*lenq+ mmsize]
mova m2, [srcq+2*lenq+2*mmsize]
mova m3, [srcq+2*lenq+3*mmsize]
psrad m0, 16
psrad m1, 16
psrad m2, 16
psrad m3, 16
packssdw m0, m1
packssdw m2, m3
mova [dstq+lenq ], m0
mova [dstq+lenq+mmsize], m2
add lenq, mmsize*2
jl .loop
%if mmsize == 8
emms
RET
%else
REP_RET
%endif
%endmacro
INIT_MMX mmx
CONV_S32_TO_S16
INIT_XMM sse2
CONV_S32_TO_S16
;------------------------------------------------------------------------------
; void ff_conv_s32_to_flt(float *dst, const int32_t *src, int len);
;------------------------------------------------------------------------------
%macro CONV_S32_TO_FLT 0
cglobal conv_s32_to_flt, 3,3,3, dst, src, len
lea lenq, [4*lend]
add srcq, lenq
add dstq, lenq
neg lenq
mova m0, [pf_s32_inv_scale]
ALIGN 16
.loop:
cvtdq2ps m1, [srcq+lenq ]
cvtdq2ps m2, [srcq+lenq+mmsize]
mulps m1, m1, m0
mulps m2, m2, m0
mova [dstq+lenq ], m1
mova [dstq+lenq+mmsize], m2
add lenq, mmsize*2
jl .loop
%if mmsize == 32
vzeroupper
RET
%else
REP_RET
%endif
%endmacro
INIT_XMM sse2
CONV_S32_TO_FLT
%if HAVE_AVX
INIT_YMM avx
CONV_S32_TO_FLT
%endif
;------------------------------------------------------------------------------
; void ff_conv_flt_to_s16(int16_t *dst, const float *src, int len);
;------------------------------------------------------------------------------
INIT_XMM sse2
cglobal conv_flt_to_s16, 3,3,5, dst, src, len
lea lenq, [2*lend]
lea srcq, [srcq+2*lenq]
add dstq, lenq
neg lenq
mova m4, [pf_s16_scale]
.loop:
mova m0, [srcq+2*lenq ]
mova m1, [srcq+2*lenq+1*mmsize]
mova m2, [srcq+2*lenq+2*mmsize]
mova m3, [srcq+2*lenq+3*mmsize]
mulps m0, m4
mulps m1, m4
mulps m2, m4
mulps m3, m4
cvtps2dq m0, m0
cvtps2dq m1, m1
cvtps2dq m2, m2
cvtps2dq m3, m3
packssdw m0, m1
packssdw m2, m3
mova [dstq+lenq ], m0
mova [dstq+lenq+mmsize], m2
add lenq, mmsize*2
jl .loop
REP_RET
;------------------------------------------------------------------------------
; void ff_conv_flt_to_s32(int32_t *dst, const float *src, int len);
;------------------------------------------------------------------------------
%macro CONV_FLT_TO_S32 0
cglobal conv_flt_to_s32, 3,3,5, dst, src, len
lea lenq, [lend*4]
add srcq, lenq
add dstq, lenq
neg lenq
mova m4, [pf_s32_scale]
.loop:
mulps m0, m4, [srcq+lenq ]
mulps m1, m4, [srcq+lenq+1*mmsize]
mulps m2, m4, [srcq+lenq+2*mmsize]
mulps m3, m4, [srcq+lenq+3*mmsize]
cvtps2dq m0, m0
cvtps2dq m1, m1
cvtps2dq m2, m2
cvtps2dq m3, m3
mova [dstq+lenq ], m0
mova [dstq+lenq+1*mmsize], m1
mova [dstq+lenq+2*mmsize], m2
mova [dstq+lenq+3*mmsize], m3
add lenq, mmsize*4
jl .loop
%if mmsize == 32
vzeroupper
RET
%else
REP_RET
%endif
%endmacro
INIT_XMM sse2
CONV_FLT_TO_S32
%if HAVE_AVX
INIT_YMM avx
CONV_FLT_TO_S32
%endif
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len, ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len,
; int channels); ; int channels);

View File

@ -22,6 +22,22 @@
#include "libavutil/cpu.h" #include "libavutil/cpu.h"
#include "libavresample/audio_convert.h" #include "libavresample/audio_convert.h"
extern void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len);
extern void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len);
extern void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len);
extern void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len);
extern void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len);
extern void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len);
extern void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len);
extern void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len);
extern void ff_conv_flt_to_s32_sse2(int32_t *dst, const float *src, int len);
extern void ff_conv_flt_to_s32_avx (int32_t *dst, const float *src, int len);
extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len);
extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len);
extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len);
@ -32,6 +48,8 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
int mm_flags = av_get_cpu_flags(); int mm_flags = av_get_cpu_flags();
if (mm_flags & AV_CPU_FLAG_MMX && HAVE_MMX) { if (mm_flags & AV_CPU_FLAG_MMX && HAVE_MMX) {
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
0, 1, 8, "MMX", ff_conv_s32_to_s16_mmx);
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx); 6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx);
} }
@ -43,5 +61,31 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
6, 16, 4, "AVX", ff_conv_fltp_to_flt_6ch_avx); 6, 16, 4, "AVX", ff_conv_fltp_to_flt_6ch_avx);
} }
if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) {
if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
0, 16, 16, "SSE2", ff_conv_s32_to_s16_sse2);
}
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16,
0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2);
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
0, 16, 8, "SSE2", ff_conv_s16_to_flt_sse2);
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
0, 16, 8, "SSE2", ff_conv_s32_to_flt_sse2);
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT,
0, 16, 16, "SSE2", ff_conv_flt_to_s16_sse2);
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
0, 16, 16, "SSE2", ff_conv_flt_to_s32_sse2);
}
if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) {
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4);
}
if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) {
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
0, 32, 16, "AVX", ff_conv_s32_to_flt_avx);
ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
0, 32, 32, "AVX", ff_conv_flt_to_s32_avx);
}
#endif #endif
} }

View File

@ -26,7 +26,11 @@
void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, int len); void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, int len);
void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul,
int len);
void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp) void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
{ {
fdsp->vector_fmul = ff_vector_fmul_neon; fdsp->vector_fmul = ff_vector_fmul_neon;
fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
} }

View File

@ -62,3 +62,51 @@ function ff_vector_fmul_neon, export=1
3: vst1.32 {d16-d19},[r0,:128]! 3: vst1.32 {d16-d19},[r0,:128]!
bx lr bx lr
endfunc endfunc
function ff_vector_fmac_scalar_neon, export=1
VFP len .req r2
VFP acc .req r3
NOVFP len .req r3
NOVFP acc .req r2
VFP vdup.32 q15, d0[0]
NOVFP vdup.32 q15, r2
bics r12, len, #15
mov acc, r0
beq 3f
vld1.32 {q0}, [r1,:128]!
vld1.32 {q8}, [acc,:128]!
vld1.32 {q1}, [r1,:128]!
vld1.32 {q9}, [acc,:128]!
1: vmla.f32 q8, q0, q15
vld1.32 {q2}, [r1,:128]!
vld1.32 {q10}, [acc,:128]!
vmla.f32 q9, q1, q15
vld1.32 {q3}, [r1,:128]!
vld1.32 {q11}, [acc,:128]!
vmla.f32 q10, q2, q15
vst1.32 {q8}, [r0,:128]!
vmla.f32 q11, q3, q15
vst1.32 {q9}, [r0,:128]!
subs r12, r12, #16
beq 2f
vld1.32 {q0}, [r1,:128]!
vld1.32 {q8}, [acc,:128]!
vst1.32 {q10}, [r0,:128]!
vld1.32 {q1}, [r1,:128]!
vld1.32 {q9}, [acc,:128]!
vst1.32 {q11}, [r0,:128]!
b 1b
2: vst1.32 {q10}, [r0,:128]!
vst1.32 {q11}, [r0,:128]!
ands len, len, #15
it eq
bxeq lr
3: vld1.32 {q0}, [r1,:128]!
vld1.32 {q8}, [acc,:128]!
vmla.f32 q8, q0, q15
vst1.32 {q8}, [r0,:128]!
subs len, len, #4
bgt 3b
bx lr
.unreq len
endfunc

View File

@ -31,9 +31,18 @@ static void vector_fmul_c(float *dst, const float *src0, const float *src1,
dst[i] = src0[i] * src1[i]; dst[i] = src0[i] * src1[i];
} }
static void vector_fmac_scalar_c(float *dst, const float *src, float mul,
int len)
{
int i;
for (i = 0; i < len; i++)
dst[i] += src[i] * mul;
}
void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
{ {
fdsp->vector_fmul = vector_fmul_c; fdsp->vector_fmul = vector_fmul_c;
fdsp->vector_fmac_scalar = vector_fmac_scalar_c;
#if ARCH_ARM #if ARCH_ARM
ff_float_dsp_init_arm(fdsp); ff_float_dsp_init_arm(fdsp);

View File

@ -35,6 +35,22 @@ typedef struct AVFloatDSPContext {
*/ */
void (*vector_fmul)(float *dst, const float *src0, const float *src1, void (*vector_fmul)(float *dst, const float *src0, const float *src1,
int len); int len);
/**
* Multiply a vector of floats by a scalar float and add to
* destination vector. Source and destination vectors must
* overlap exactly or not at all.
*
* @param dst result vector
* constraints: 32-byte aligned
* @param src input vector
* constraints: 32-byte aligned
* @param mul scalar value
* @param len length of vector
* constraints: multiple of 16
*/
void (*vector_fmac_scalar)(float *dst, const float *src, float mul,
int len);
} AVFloatDSPContext; } AVFloatDSPContext;
/** /**

View File

@ -94,6 +94,8 @@ void *av_malloc(size_t size)
if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
if (posix_memalign(&ptr,ALIGN,size)) if (posix_memalign(&ptr,ALIGN,size))
ptr = NULL; ptr = NULL;
#elif HAVE_ALIGNED_MALLOC
ptr = _aligned_malloc(size, ALIGN);
#elif HAVE_MEMALIGN #elif HAVE_MEMALIGN
ptr = memalign(ALIGN,size); ptr = memalign(ALIGN,size);
/* Why 64? /* Why 64?
@ -145,6 +147,8 @@ void *av_realloc(void *ptr, size_t size)
ptr= realloc((char*)ptr - diff, size + diff); ptr= realloc((char*)ptr - diff, size + diff);
if(ptr) ptr = (char*)ptr + diff; if(ptr) ptr = (char*)ptr + diff;
return ptr; return ptr;
#elif HAVE_ALIGNED_MALLOC
return _aligned_realloc(ptr, size + !size, ALIGN);
#else #else
return realloc(ptr, size + !size); return realloc(ptr, size + !size);
#endif #endif
@ -170,6 +174,8 @@ void av_free(void *ptr)
#if CONFIG_MEMALIGN_HACK #if CONFIG_MEMALIGN_HACK
if (ptr) if (ptr)
free((char*)ptr - ((char*)ptr)[-1]); free((char*)ptr - ((char*)ptr)[-1]);
#elif HAVE_ALIGNED_MALLOC
_aligned_free(ptr);
#else #else
free(ptr); free(ptr);
#endif #endif

View File

@ -21,6 +21,7 @@
;****************************************************************************** ;******************************************************************************
%include "x86inc.asm" %include "x86inc.asm"
%include "x86util.asm"
SECTION .text SECTION .text
@ -55,3 +56,49 @@ VECTOR_FMUL
INIT_YMM avx INIT_YMM avx
VECTOR_FMUL VECTOR_FMUL
%endif %endif
;------------------------------------------------------------------------------
; void ff_vector_fmac_scalar(float *dst, const float *src, float mul, int len)
;------------------------------------------------------------------------------
%macro VECTOR_FMAC_SCALAR 0
%if UNIX64
cglobal vector_fmac_scalar, 3,3,3, dst, src, len
%else
cglobal vector_fmac_scalar, 4,4,3, dst, src, mul, len
%endif
%if WIN64
SWAP 0, 2
%endif
%if ARCH_X86_32
VBROADCASTSS m0, mulm
%else
shufps xmm0, xmm0, 0
%if cpuflag(avx)
vinsertf128 m0, m0, xmm0, 1
%endif
%endif
lea lenq, [lend*4-2*mmsize]
.loop
mulps m1, m0, [srcq+lenq ]
mulps m2, m0, [srcq+lenq+mmsize]
addps m1, m1, [dstq+lenq ]
addps m2, m2, [dstq+lenq+mmsize]
mova [dstq+lenq ], m1
mova [dstq+lenq+mmsize], m2
sub lenq, 2*mmsize
jge .loop
%if mmsize == 32
vzeroupper
RET
%else
REP_RET
%endif
%endmacro
INIT_XMM sse
VECTOR_FMAC_SCALAR
%if HAVE_AVX
INIT_YMM avx
VECTOR_FMAC_SCALAR
%endif

View File

@ -26,6 +26,11 @@ extern void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
extern void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1, extern void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1,
int len); int len);
extern void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul,
int len);
extern void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul,
int len);
void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
{ {
#if HAVE_YASM #if HAVE_YASM
@ -33,9 +38,11 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) { if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) {
fdsp->vector_fmul = ff_vector_fmul_sse; fdsp->vector_fmul = ff_vector_fmul_sse;
fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse;
} }
if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) { if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) {
fdsp->vector_fmul = ff_vector_fmul_avx; fdsp->vector_fmul = ff_vector_fmul_avx;
fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx;
} }
#endif #endif
} }