Browse code

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>

Michael Niedermayer authored on 2012/06/20 03:52:00
Showing 44 changed files
... ...
@@ -10,6 +10,7 @@ version next:
10 10
 - atempo filter
11 11
 - ffprobe -show_data option
12 12
 - RTMPT protocol support
13
+- iLBC encoding/decoding via libilbc
13 14
 
14 15
 
15 16
 version 0.11:
... ...
@@ -180,6 +180,7 @@ External library support:
180 180
   --enable-libfaac         enable FAAC support via libfaac [no]
181 181
   --enable-libfreetype     enable libfreetype [no]
182 182
   --enable-libgsm          enable GSM support via libgsm [no]
183
+  --enable-libilbc         enable iLBC de/encoding via libilbc [no]
183 184
   --enable-libmodplug      enable ModPlug via libmodplug [no]
184 185
   --enable-libmp3lame      enable MP3 encoding via libmp3lame [no]
185 186
   --enable-libnut          enable NUT (de)muxing via libnut,
... ...
@@ -1051,6 +1052,7 @@ CONFIG_LIST="
1051 1051
     libfaac
1052 1052
     libfreetype
1053 1053
     libgsm
1054
+    libilbc
1054 1055
     libmodplug
1055 1056
     libmp3lame
1056 1057
     libnut
... ...
@@ -1168,6 +1170,7 @@ HAVE_LIST="
1168 1168
     $ARCH_EXT_LIST
1169 1169
     $HAVE_LIST_PUB
1170 1170
     $THREADS_LIST
1171
+    aligned_malloc
1171 1172
     aligned_stack
1172 1173
     alsa_asoundlib_h
1173 1174
     altivec_h
... ...
@@ -1588,6 +1591,8 @@ libgsm_decoder_deps="libgsm"
1588 1588
 libgsm_encoder_deps="libgsm"
1589 1589
 libgsm_ms_decoder_deps="libgsm"
1590 1590
 libgsm_ms_encoder_deps="libgsm"
1591
+libilbc_decoder_deps="libilbc"
1592
+libilbc_encoder_deps="libilbc"
1591 1593
 libmodplug_demuxer_deps="libmodplug"
1592 1594
 libmp3lame_encoder_deps="libmp3lame"
1593 1595
 libopencore_amrnb_decoder_deps="libopencore_amrnb"
... ...
@@ -3144,6 +3149,7 @@ check_func  ${malloc_prefix}memalign            && enable memalign
3144 3144
 check_func  mkstemp
3145 3145
 check_func  mmap
3146 3146
 check_func  ${malloc_prefix}posix_memalign      && enable posix_memalign
3147
+check_func_headers malloc.h _aligned_malloc     && enable aligned_malloc
3147 3148
 check_func  setrlimit
3148 3149
 check_func  strerror_r
3149 3150
 check_func  strptime
... ...
@@ -3254,6 +3260,7 @@ enabled libcelt    && require libcelt celt/celt.h celt_decode -lcelt0 &&
3254 3254
 enabled libfaac    && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
3255 3255
 enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType
3256 3256
 enabled libgsm     && require  libgsm gsm/gsm.h gsm_create -lgsm
3257
+enabled libilbc    && require  libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
3257 3258
 enabled libmodplug && require  libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug
3258 3259
 enabled libmp3lame && require  "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
3259 3260
 enabled libnut     && require  libnut libnut.h nut_demuxer_init -lnut
... ...
@@ -3522,7 +3529,7 @@ if test $target_os = "haiku"; then
3522 3522
     disable posix_memalign
3523 3523
 fi
3524 3524
 
3525
-! enabled_any memalign posix_memalign &&
3525
+! enabled_any memalign posix_memalign aligned_malloc &&
3526 3526
     enabled_any $need_memalign && enable memalign_hack
3527 3527
 
3528 3528
 # add_dep lib dep
... ...
@@ -3628,6 +3635,7 @@ echo "libcelt enabled           ${libcelt-no}"
3628 3628
 echo "libdc1394 support         ${libdc1394-no}"
3629 3629
 echo "libfaac enabled           ${libfaac-no}"
3630 3630
 echo "libgsm enabled            ${libgsm-no}"
3631
+echo "libilbc enabled           ${libilbc-no}"
3631 3632
 echo "libmodplug enabled        ${libmodplug-no}"
3632 3633
 echo "libmp3lame enabled        ${libmp3lame-no}"
3633 3634
 echo "libnut enabled            ${libnut-no}"
... ...
@@ -93,6 +93,17 @@ x264 is under the GNU Public License Version 2 or later
93 93
 details), you must upgrade FFmpeg's license to GPL in order to use it.
94 94
 @end float
95 95
 
96
+@section libilbc
97
+
98
+iLBC is a narrowband speech codec that has been made freely available
99
+by Google as part of the WebRTC project. libilbc is a packaging friendly
100
+copy of the iLBC codec. Libav can make use of the libilbc library for
101
+iLBC encoding and decoding.
102
+
103
+Go to @url{https://github.com/dekkers/libilbc} and follow the instructions for
104
+installing the library. Then pass @code{--enable-libilbc} to configure to
105
+enable it.
106
+
96 107
 
97 108
 
98 109
 @chapter Supported File Formats, Codecs or Features
... ...
@@ -191,6 +202,7 @@ library:
191 191
 @item IEC61937 encapsulation @tab X @tab X
192 192
 @item IFF                       @tab   @tab X
193 193
     @tab Interchange File Format
194
+@item iLBC                      @tab X @tab X
194 195
 @item Interplay MVE             @tab   @tab X
195 196
     @tab Format used in various Interplay computer games.
196 197
 @item IV8                       @tab   @tab X
... ...
@@ -749,6 +761,8 @@ following image formats are supported:
749 749
 @item GSM Microsoft variant  @tab  E  @tab  X
750 750
     @tab encoding supported through external library libgsm
751 751
 @item IAC (Indeo Audio Coder)  @tab     @tab  X
752
+@item iLBC (Internet Low Bitrate Codec) @tab  E  @tab  E
753
+    @tab encoding and decoding supported through external library libilbc
752 754
 @item IMC (Intel Music Coder)  @tab     @tab  X
753 755
 @item MACE (Macintosh Audio Compression/Expansion) 3:1  @tab     @tab  X
754 756
 @item MACE (Macintosh Audio Compression/Expansion) 6:1  @tab     @tab  X
... ...
@@ -247,6 +247,10 @@ times to construct arbitrary AMF sequences.
247 247
 Version of the Flash plugin used to run the SWF player. The default
248 248
 is LNX 9,0,124,2.
249 249
 
250
+@item rtmp_flush_interval
251
+Number of packets flushed in the same request (RTMPT only). The default
252
+is 10.
253
+
250 254
 @item rtmp_live
251 255
 Specify that the media is a live stream. No resuming or seeking in
252 256
 live streams is possible. The default value is @code{any}, which means the
... ...
@@ -659,6 +659,8 @@ OBJS-$(CONFIG_LIBGSM_DECODER)             += libgsm.o
659 659
 OBJS-$(CONFIG_LIBGSM_ENCODER)             += libgsm.o
660 660
 OBJS-$(CONFIG_LIBGSM_MS_DECODER)          += libgsm.o
661 661
 OBJS-$(CONFIG_LIBGSM_MS_ENCODER)          += libgsm.o
662
+OBJS-$(CONFIG_LIBILBC_DECODER)            += libilbc.o
663
+OBJS-$(CONFIG_LIBILBC_ENCODER)            += libilbc.o
662 664
 OBJS-$(CONFIG_LIBMP3LAME_ENCODER)         += libmp3lame.o mpegaudiodecheader.o \
663 665
                                              audio_frame_queue.o
664 666
 OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER)  += libopencore-amr.o \
... ...
@@ -410,6 +410,7 @@ void avcodec_register_all(void)
410 410
     REGISTER_ENCODER (LIBFAAC, libfaac);
411 411
     REGISTER_ENCDEC  (LIBGSM, libgsm);
412 412
     REGISTER_ENCDEC  (LIBGSM_MS, libgsm_ms);
413
+    REGISTER_ENCDEC  (LIBILBC, libilbc);
413 414
     REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
414 415
     REGISTER_ENCDEC  (LIBOPENCORE_AMRNB, libopencore_amrnb);
415 416
     REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb);
... ...
@@ -154,8 +154,6 @@ void ff_vector_fmul_window_neon(float *dst, const float *src0,
154 154
                                 const float *src1, const float *win, int len);
155 155
 void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul,
156 156
                                 int len);
157
-void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul,
158
-                                int len);
159 157
 void ff_butterflies_float_neon(float *v1, float *v2, int len);
160 158
 float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len);
161 159
 void ff_vector_fmul_reverse_neon(float *dst, const float *src0,
... ...
@@ -329,7 +327,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx)
329 329
 
330 330
     c->vector_fmul_window         = ff_vector_fmul_window_neon;
331 331
     c->vector_fmul_scalar         = ff_vector_fmul_scalar_neon;
332
-    c->vector_fmac_scalar         = ff_vector_fmac_scalar_neon;
333 332
     c->butterflies_float          = ff_butterflies_float_neon;
334 333
     c->scalarproduct_float        = ff_scalarproduct_float_neon;
335 334
     c->vector_fmul_reverse        = ff_vector_fmul_reverse_neon;
... ...
@@ -682,54 +682,6 @@ NOVFP   vdup.32         q8,  r2
682 682
         .unreq          len
683 683
 endfunc
684 684
 
685
-function ff_vector_fmac_scalar_neon, export=1
686
-VFP     len .req r2
687
-VFP     acc .req r3
688
-NOVFP   len .req r3
689
-NOVFP   acc .req r2
690
-VFP     vdup.32         q15, d0[0]
691
-NOVFP   vdup.32         q15, r2
692
-        bics            r12, len, #15
693
-        mov             acc, r0
694
-        beq             3f
695
-        vld1.32         {q0},     [r1,:128]!
696
-        vld1.32         {q8},     [acc,:128]!
697
-        vld1.32         {q1},     [r1,:128]!
698
-        vld1.32         {q9},     [acc,:128]!
699
-1:      vmla.f32        q8,  q0,  q15
700
-        vld1.32         {q2},     [r1,:128]!
701
-        vld1.32         {q10},    [acc,:128]!
702
-        vmla.f32        q9,  q1,  q15
703
-        vld1.32         {q3},     [r1,:128]!
704
-        vld1.32         {q11},    [acc,:128]!
705
-        vmla.f32        q10, q2,  q15
706
-        vst1.32         {q8},     [r0,:128]!
707
-        vmla.f32        q11, q3,  q15
708
-        vst1.32         {q9},     [r0,:128]!
709
-        subs            r12, r12, #16
710
-        beq             2f
711
-        vld1.32         {q0},     [r1,:128]!
712
-        vld1.32         {q8},     [acc,:128]!
713
-        vst1.32         {q10},    [r0,:128]!
714
-        vld1.32         {q1},     [r1,:128]!
715
-        vld1.32         {q9},     [acc,:128]!
716
-        vst1.32         {q11},    [r0,:128]!
717
-        b               1b
718
-2:      vst1.32         {q10},    [r0,:128]!
719
-        vst1.32         {q11},    [r0,:128]!
720
-        ands            len, len, #15
721
-        it              eq
722
-        bxeq            lr
723
-3:      vld1.32         {q0},     [r1,:128]!
724
-        vld1.32         {q8},     [acc,:128]!
725
-        vmla.f32        q8,  q0,  q15
726
-        vst1.32         {q8},     [r0,:128]!
727
-        subs            len, len, #4
728
-        bgt             3b
729
-        bx              lr
730
-        .unreq          len
731
-endfunc
732
-
733 685
 function ff_butterflies_float_neon, export=1
734 686
 1:      vld1.32         {q0},[r0,:128]
735 687
         vld1.32         {q1},[r1,:128]
... ...
@@ -407,6 +407,7 @@ enum CodecID {
407 407
     CODEC_ID_BMV_AUDIO,
408 408
     CODEC_ID_RALF,
409 409
     CODEC_ID_IAC,
410
+    CODEC_ID_ILBC,
410 411
     CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
411 412
     CODEC_ID_8SVX_RAW    = MKBETAG('8','S','V','X'),
412 413
     CODEC_ID_SONIC       = MKBETAG('S','O','N','C'),
... ...
@@ -3470,6 +3471,9 @@ void av_destruct_packet(AVPacket *pkt);
3470 3470
 /**
3471 3471
  * Initialize optional fields of a packet with default values.
3472 3472
  *
3473
+ * Note, this does not touch the data and size members, which have to be
3474
+ * initialized separately.
3475
+ *
3473 3476
  * @param pkt packet
3474 3477
  */
3475 3478
 void av_init_packet(AVPacket *pkt);
... ...
@@ -27,6 +27,7 @@
27 27
 #include <stdio.h>
28 28
 
29 29
 #include "libavutil/common.h"
30
+#include "libavutil/float_dsp.h"
30 31
 #include "libavutil/intmath.h"
31 32
 #include "libavutil/intreadwrite.h"
32 33
 #include "libavutil/mathematics.h"
... ...
@@ -384,7 +385,7 @@ typedef struct {
384 384
     int profile;
385 385
 
386 386
     int debug_flag;             ///< used for suppressing repeated error messages output
387
-    DSPContext dsp;
387
+    AVFloatDSPContext fdsp;
388 388
     FFTContext imdct;
389 389
     SynthFilterContext synth;
390 390
     DCADSPContext dcadsp;
... ...
@@ -2042,8 +2043,8 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
2042 2042
             float *back_chan = s->samples + s->channel_order_tab[s->xch_base_channel]     * 256;
2043 2043
             float *lt_chan   = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256;
2044 2044
             float *rt_chan   = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256;
2045
-            s->dsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
2046
-            s->dsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
2045
+            s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
2046
+            s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
2047 2047
         }
2048 2048
 
2049 2049
         if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
... ...
@@ -2085,7 +2086,7 @@ static av_cold int dca_decode_init(AVCodecContext *avctx)
2085 2085
     s->avctx = avctx;
2086 2086
     dca_init_vlcs();
2087 2087
 
2088
-    ff_dsputil_init(&s->dsp, avctx);
2088
+    avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
2089 2089
     ff_mdct_init(&s->imdct, 6, 1, 1.0);
2090 2090
     ff_synth_filter_init(&s->synth);
2091 2091
     ff_dcadsp_init(&s->dcadsp);
... ...
@@ -127,7 +127,7 @@ static const enum PixelFormat dirac_pix_fmt[2][3] = {
127 127
 static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,
128 128
                                    dirac_source_params *source)
129 129
 {
130
-    AVRational frame_rate = (AVRational){0,0};
130
+    AVRational frame_rate = {0,0};
131 131
     unsigned luma_depth = 8, luma_offset = 16;
132 132
     int idx;
133 133
 
... ...
@@ -2509,14 +2509,6 @@ static void vector_fmul_scalar_c(float *dst, const float *src, float mul,
2509 2509
         dst[i] = src[i] * mul;
2510 2510
 }
2511 2511
 
2512
-static void vector_fmac_scalar_c(float *dst, const float *src, float mul,
2513
-                                 int len)
2514
-{
2515
-    int i;
2516
-    for (i = 0; i < len; i++)
2517
-        dst[i] += src[i] * mul;
2518
-}
2519
-
2520 2512
 static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2,
2521 2513
                                 int len)
2522 2514
 {
... ...
@@ -3060,7 +3052,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx)
3060 3060
     c->butterflies_float = butterflies_float_c;
3061 3061
     c->butterflies_float_interleave = butterflies_float_interleave_c;
3062 3062
     c->vector_fmul_scalar = vector_fmul_scalar_c;
3063
-    c->vector_fmac_scalar = vector_fmac_scalar_c;
3064 3063
 
3065 3064
     c->shrink[0]= av_image_copy_plane;
3066 3065
     c->shrink[1]= ff_shrink22;
... ...
@@ -421,17 +421,6 @@ typedef struct DSPContext {
421 421
     void (*vector_fmul_scalar)(float *dst, const float *src, float mul,
422 422
                                int len);
423 423
     /**
424
-     * Multiply a vector of floats by a scalar float and add to
425
-     * destination vector.  Source and destination vectors must
426
-     * overlap exactly or not at all.
427
-     * @param dst result vector, 16-byte aligned
428
-     * @param src input vector, 16-byte aligned
429
-     * @param mul scalar value
430
-     * @param len length of vector, multiple of 4
431
-     */
432
-    void (*vector_fmac_scalar)(float *dst, const float *src, float mul,
433
-                               int len);
434
-    /**
435 424
      * Calculate the scalar product of two vectors of floats.
436 425
      * @param v1  first vector, 16-byte aligned
437 426
      * @param v2  second vector, 16-byte aligned
438 427
new file mode 100644
... ...
@@ -0,0 +1,209 @@
0
+/*
1
+ * iLBC decoder/encoder stub
2
+ * Copyright (c) 2012 Martin Storsjo
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include <ilbc.h>
22
+
23
+#include "avcodec.h"
24
+#include "libavutil/opt.h"
25
+#include "internal.h"
26
+
27
+static int get_mode(AVCodecContext *avctx)
28
+{
29
+    if (avctx->block_align == 38)
30
+        return 20;
31
+    else if (avctx->block_align == 50)
32
+        return 30;
33
+    else if (avctx->bit_rate > 0)
34
+        return avctx->bit_rate <= 14000 ? 30 : 20;
35
+    else
36
+        return -1;
37
+}
38
+
39
+typedef struct ILBCDecContext {
40
+    const AVClass *class;
41
+    AVFrame frame;
42
+    iLBC_Dec_Inst_t decoder;
43
+    int enhance;
44
+} ILBCDecContext;
45
+
46
+static const AVOption ilbc_dec_options[] = {
47
+    { "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 },
48
+    { NULL }
49
+};
50
+
51
+static const AVClass ilbc_dec_class = {
52
+    "libilbc", av_default_item_name, ilbc_dec_options, LIBAVUTIL_VERSION_INT
53
+};
54
+
55
+static av_cold int ilbc_decode_init(AVCodecContext *avctx)
56
+{
57
+    ILBCDecContext *s  = avctx->priv_data;
58
+    int mode;
59
+
60
+    if ((mode = get_mode(avctx)) < 0) {
61
+        av_log(avctx, AV_LOG_ERROR, "iLBC frame mode not indicated\n");
62
+        return AVERROR(EINVAL);
63
+    }
64
+
65
+    WebRtcIlbcfix_InitDecode(&s->decoder, mode, s->enhance);
66
+    avcodec_get_frame_defaults(&s->frame);
67
+    avctx->coded_frame = &s->frame;
68
+
69
+    avctx->channels = 1;
70
+    avctx->sample_rate = 8000;
71
+    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
72
+
73
+    return 0;
74
+}
75
+
76
+static int ilbc_decode_frame(AVCodecContext *avctx, void *data,
77
+                             int *got_frame_ptr, AVPacket *avpkt)
78
+{
79
+    const uint8_t *buf = avpkt->data;
80
+    int buf_size       = avpkt->size;
81
+    ILBCDecContext *s  = avctx->priv_data;
82
+    int ret;
83
+
84
+    if (s->decoder.no_of_bytes > buf_size) {
85
+        av_log(avctx, AV_LOG_ERROR, "iLBC frame too short (%u, should be %u)\n",
86
+               buf_size, s->decoder.no_of_bytes);
87
+        return AVERROR_INVALIDDATA;
88
+    }
89
+
90
+    s->frame.nb_samples = s->decoder.blockl;
91
+    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
92
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
93
+        return ret;
94
+    }
95
+
96
+    WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) s->frame.data[0],
97
+                             (const WebRtc_UWord16*) buf, &s->decoder, 1);
98
+
99
+    *got_frame_ptr   = 1;
100
+    *(AVFrame *)data = s->frame;
101
+
102
+    return s->decoder.no_of_bytes;
103
+}
104
+
105
+AVCodec ff_libilbc_decoder = {
106
+    .name           = "libilbc",
107
+    .type           = AVMEDIA_TYPE_AUDIO,
108
+    .id             = CODEC_ID_ILBC,
109
+    .priv_data_size = sizeof(ILBCDecContext),
110
+    .init           = ilbc_decode_init,
111
+    .decode         = ilbc_decode_frame,
112
+    .capabilities   = CODEC_CAP_DR1,
113
+    .long_name      = NULL_IF_CONFIG_SMALL("Internet Low Bitrate Codec (iLBC)"),
114
+    .priv_class     = &ilbc_dec_class,
115
+};
116
+
117
+typedef struct ILBCEncContext {
118
+    const AVClass *class;
119
+    iLBC_Enc_Inst_t encoder;
120
+    int mode;
121
+} ILBCEncContext;
122
+
123
+static const AVOption ilbc_enc_options[] = {
124
+    { "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 },
125
+    { NULL }
126
+};
127
+
128
+static const AVClass ilbc_enc_class = {
129
+    "libilbc", av_default_item_name, ilbc_enc_options, LIBAVUTIL_VERSION_INT
130
+};
131
+
132
+static av_cold int ilbc_encode_init(AVCodecContext *avctx)
133
+{
134
+    ILBCEncContext *s = avctx->priv_data;
135
+    int mode;
136
+
137
+    if (avctx->sample_rate != 8000) {
138
+        av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
139
+        return AVERROR(EINVAL);
140
+    }
141
+
142
+    if (avctx->channels != 1) {
143
+        av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
144
+        return AVERROR(EINVAL);
145
+    }
146
+
147
+    if ((mode = get_mode(avctx)) > 0)
148
+        s->mode = mode;
149
+    else
150
+        s->mode = s->mode != 30 ? 20 : 30;
151
+    WebRtcIlbcfix_InitEncode(&s->encoder, s->mode);
152
+
153
+    avctx->block_align = s->encoder.no_of_bytes;
154
+    avctx->frame_size  = s->encoder.blockl;
155
+#if FF_API_OLD_ENCODE_AUDIO
156
+    avctx->coded_frame = avcodec_alloc_frame();
157
+    if (!avctx->coded_frame)
158
+        return AVERROR(ENOMEM);
159
+#endif
160
+
161
+    return 0;
162
+}
163
+
164
+static av_cold int ilbc_encode_close(AVCodecContext *avctx)
165
+{
166
+#if FF_API_OLD_ENCODE_AUDIO
167
+    av_freep(&avctx->coded_frame);
168
+#endif
169
+    return 0;
170
+}
171
+
172
+static int ilbc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
173
+                             const AVFrame *frame, int *got_packet_ptr)
174
+{
175
+    ILBCEncContext *s = avctx->priv_data;
176
+    int ret;
177
+
178
+    if ((ret = ff_alloc_packet(avpkt, 50))) {
179
+        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
180
+        return ret;
181
+    }
182
+
183
+    WebRtcIlbcfix_EncodeImpl((WebRtc_UWord16*) avpkt->data, (const WebRtc_Word16*) frame->data[0], &s->encoder);
184
+
185
+    avpkt->size     = s->encoder.no_of_bytes;
186
+    *got_packet_ptr = 1;
187
+    return 0;
188
+}
189
+
190
+static const AVCodecDefault ilbc_encode_defaults[] = {
191
+    { "b", "0" },
192
+    { NULL }
193
+};
194
+
195
+AVCodec ff_libilbc_encoder = {
196
+    .name           = "libilbc",
197
+    .type           = AVMEDIA_TYPE_AUDIO,
198
+    .id             = CODEC_ID_ILBC,
199
+    .priv_data_size = sizeof(ILBCEncContext),
200
+    .init           = ilbc_encode_init,
201
+    .encode2        = ilbc_encode_frame,
202
+    .close          = ilbc_encode_close,
203
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
204
+                                                     AV_SAMPLE_FMT_NONE },
205
+    .long_name      = NULL_IF_CONFIG_SMALL("Internet Low Bitrate Codec (iLBC)"),
206
+    .defaults       = ilbc_encode_defaults,
207
+    .priv_class     = &ilbc_enc_class,
208
+};
... ...
@@ -514,14 +514,6 @@ static double predict_size(Predictor *p, double q, double var)
514 514
      return p->coeff*var / (q*p->count);
515 515
 }
516 516
 
517
-/*
518
-static double predict_qp(Predictor *p, double size, double var)
519
-{
520
-//printf("coeff:%f, count:%f, var:%f, size:%f//\n", p->coeff, p->count, var, size);
521
-     return p->coeff*var / (size*p->count);
522
-}
523
-*/
524
-
525 517
 static void update_predictor(Predictor *p, double q, double var, double size)
526 518
 {
527 519
     double new_coeff= size*q / (var + 1);
... ...
@@ -561,10 +553,6 @@ static void adaptive_quantization(MpegEncContext *s, double q){
561 561
         int mb_y = mb_xy / s->mb_stride;
562 562
         int mb_distance;
563 563
         float mb_factor = 0.0;
564
-#if 0
565
-        if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune
566
-        if(temp_cplx < q/3) temp_cplx= q/3; //FIXME finetune
567
-#endif
568 564
         if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune
569 565
         if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune
570 566
 
... ...
@@ -2138,6 +2138,11 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes)
2138 2138
             case 29: return 288;
2139 2139
             case 37: return 480;
2140 2140
             }
2141
+        } else if (id == CODEC_ID_ILBC) {
2142
+            switch (ba) {
2143
+            case 38: return 160;
2144
+            case 50: return 240;
2145
+            }
2141 2146
         }
2142 2147
     }
2143 2148
 
... ...
@@ -27,7 +27,7 @@
27 27
  */
28 28
 
29 29
 #define LIBAVCODEC_VERSION_MAJOR 54
30
-#define LIBAVCODEC_VERSION_MINOR  25
30
+#define LIBAVCODEC_VERSION_MINOR  26
31 31
 #define LIBAVCODEC_VERSION_MICRO 100
32 32
 
33 33
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -32,6 +32,7 @@
32 32
 #include "libavutil/audio_fifo.h"
33 33
 #include "libavutil/avassert.h"
34 34
 #include "libavutil/avstring.h"
35
+#include "libavutil/float_dsp.h"
35 36
 #include "libavutil/mathematics.h"
36 37
 #include "libavutil/opt.h"
37 38
 #include "libavutil/samplefmt.h"
... ...
@@ -152,6 +153,7 @@ static int frame_list_add_frame(FrameList *frame_list, int nb_samples, int64_t p
152 152
 
153 153
 typedef struct MixContext {
154 154
     const AVClass *class;       /**< class for AVOptions */
155
+    AVFloatDSPContext fdsp;
155 156
 
156 157
     int nb_inputs;              /**< number of inputs */
157 158
     int active_inputs;          /**< number of input currently active */
... ...
@@ -160,6 +162,7 @@ typedef struct MixContext {
160 160
 
161 161
     int nb_channels;            /**< number of channels */
162 162
     int sample_rate;            /**< sample rate */
163
+    int planar;
163 164
     AVAudioFifo **fifos;        /**< audio fifo for each input */
164 165
     uint8_t *input_state;       /**< current state of each input */
165 166
     float *input_scale;         /**< mixing scale factor for each input */
... ...
@@ -224,6 +227,7 @@ static int config_output(AVFilterLink *outlink)
224 224
     int i;
225 225
     char buf[64];
226 226
 
227
+    s->planar          = av_sample_fmt_is_planar(outlink->format);
227 228
     s->sample_rate     = outlink->sample_rate;
228 229
     outlink->time_base = (AVRational){ 1, outlink->sample_rate };
229 230
     s->next_pts        = AV_NOPTS_VALUE;
... ...
@@ -264,14 +268,6 @@ static int config_output(AVFilterLink *outlink)
264 264
     return 0;
265 265
 }
266 266
 
267
-/* TODO: move optimized version from DSPContext to libavutil */
268
-static void vector_fmac_scalar(float *dst, const float *src, float mul, int len)
269
-{
270
-    int i;
271
-    for (i = 0; i < len; i++)
272
-        dst[i] += src[i] * mul;
273
-}
274
-
275 267
 /**
276 268
  * Read samples from the input FIFOs, mix, and write to the output link.
277 269
  */
... ...
@@ -294,11 +290,20 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
294 294
 
295 295
     for (i = 0; i < s->nb_inputs; i++) {
296 296
         if (s->input_state[i] == INPUT_ON) {
297
+            int planes, plane_size, p;
298
+
297 299
             av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data,
298 300
                                nb_samples);
299
-            vector_fmac_scalar((float *)out_buf->extended_data[0],
300
-                               (float *) in_buf->extended_data[0],
301
-                               s->input_scale[i], nb_samples * s->nb_channels);
301
+
302
+            planes     = s->planar ? s->nb_channels : 1;
303
+            plane_size = nb_samples * (s->planar ? 1 : s->nb_channels);
304
+            plane_size = FFALIGN(plane_size, 16);
305
+
306
+            for (p = 0; p < planes; p++) {
307
+                s->fdsp.vector_fmac_scalar((float *)out_buf->extended_data[p],
308
+                                           (float *) in_buf->extended_data[p],
309
+                                           s->input_scale[i], plane_size);
310
+            }
302 311
         }
303 312
     }
304 313
     avfilter_unref_buffer(in_buf);
... ...
@@ -501,6 +506,8 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque)
501 501
         ff_insert_inpad(ctx, i, &pad);
502 502
     }
503 503
 
504
+    avpriv_float_dsp_init(&s->fdsp, 0);
505
+
504 506
     return 0;
505 507
 }
506 508
 
... ...
@@ -527,6 +534,7 @@ static int query_formats(AVFilterContext *ctx)
527 527
 {
528 528
     AVFilterFormats *formats = NULL;
529 529
     ff_add_format(&formats, AV_SAMPLE_FMT_FLT);
530
+    ff_add_format(&formats, AV_SAMPLE_FMT_FLTP);
530 531
     ff_set_common_formats(ctx, formats);
531 532
     ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
532 533
     ff_set_common_samplerates(ctx, ff_all_samplerates());
... ...
@@ -123,6 +123,8 @@ OBJS-$(CONFIG_ICO_DEMUXER)               += icodec.o
123 123
 OBJS-$(CONFIG_IDCIN_DEMUXER)             += idcin.o
124 124
 OBJS-$(CONFIG_IDF_DEMUXER)               += bintext.o
125 125
 OBJS-$(CONFIG_IFF_DEMUXER)               += iff.o
126
+OBJS-$(CONFIG_ILBC_DEMUXER)              += ilbc.o
127
+OBJS-$(CONFIG_ILBC_MUXER)                += ilbc.o
126 128
 OBJS-$(CONFIG_IMAGE2_DEMUXER)            += img2dec.o img2.o
127 129
 OBJS-$(CONFIG_IMAGE2_MUXER)              += img2enc.o img2.o
128 130
 OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER)        += img2dec.o img2.o
... ...
@@ -281,6 +283,7 @@ OBJS-$(CONFIG_RTPDEC)                    += rdt.o         \
281 281
                                             rtpdec_h263.o \
282 282
                                             rtpdec_h263_rfc2190.o \
283 283
                                             rtpdec_h264.o \
284
+                                            rtpdec_ilbc.o \
284 285
                                             rtpdec_latm.o \
285 286
                                             rtpdec_mpeg4.o \
286 287
                                             rtpdec_qcelp.o \
... ...
@@ -116,6 +116,7 @@ void av_register_all(void)
116 116
     REGISTER_DEMUXER  (IDCIN, idcin);
117 117
     REGISTER_DEMUXER  (IDF, idf);
118 118
     REGISTER_DEMUXER  (IFF, iff);
119
+    REGISTER_MUXDEMUX (ILBC, ilbc);
119 120
     REGISTER_MUXDEMUX (IMAGE2, image2);
120 121
     REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe);
121 122
     REGISTER_DEMUXER  (INGENIENT, ingenient);
... ...
@@ -759,33 +759,6 @@ static int flv_read_seek(AVFormatContext *s, int stream_index,
759 759
     return avio_seek_time(s->pb, stream_index, ts, flags);
760 760
 }
761 761
 
762
-#if 0 /* don't know enough to implement this */
763
-static int flv_read_seek2(AVFormatContext *s, int stream_index,
764
-    int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
765
-{
766
-    int ret = AVERROR(ENOSYS);
767
-
768
-    if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD;
769
-
770
-    if (!s->pb->seekable) {
771
-        if (stream_index < 0) {
772
-            stream_index = av_find_default_stream_index(s);
773
-            if (stream_index < 0)
774
-                return -1;
775
-
776
-            /* timestamp for default must be expressed in AV_TIME_BASE units */
777
-            ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE,
778
-                flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
779
-        }
780
-        ret = avio_seek_time(s->pb, stream_index, ts, flags);
781
-    }
782
-
783
-    if (ret == AVERROR(ENOSYS))
784
-        ret = av_seek_frame(s, stream_index, ts, flags);
785
-    return ret;
786
-}
787
-#endif
788
-
789 762
 AVInputFormat ff_flv_demuxer = {
790 763
     .name           = "flv",
791 764
     .long_name      = NULL_IF_CONFIG_SMALL("FLV format"),
... ...
@@ -794,9 +767,6 @@ AVInputFormat ff_flv_demuxer = {
794 794
     .read_header    = flv_read_header,
795 795
     .read_packet    = flv_read_packet,
796 796
     .read_seek      = flv_read_seek,
797
-#if 0
798
-    .read_seek2     = flv_read_seek2,
799
-#endif
800 797
     .read_close     = flv_read_close,
801 798
     .extensions     = "flv",
802 799
 };
... ...
@@ -308,15 +308,15 @@ static int process_line(URLContext *h, char *line, int line_count,
308 308
             strcpy(s->location, p);
309 309
             *new_location = 1;
310 310
         } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
311
-            s->filesize = atoll(p);
311
+            s->filesize = strtoll(p, NULL, 10);
312 312
         } else if (!av_strcasecmp (tag, "Content-Range")) {
313 313
             /* "bytes $from-$to/$document_size" */
314 314
             const char *slash;
315 315
             if (!strncmp (p, "bytes ", 6)) {
316 316
                 p += 6;
317
-                s->off = atoll(p);
317
+                s->off = strtoll(p, NULL, 10);
318 318
                 if ((slash = strchr(p, '/')) && strlen(slash) > 0)
319
-                    s->filesize = atoll(slash+1);
319
+                    s->filesize = strtoll(slash+1, NULL, 10);
320 320
             }
321 321
             h->is_streamed = 0; /* we _can_ in fact seek */
322 322
         } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
323 323
new file mode 100644
... ...
@@ -0,0 +1,141 @@
0
+/*
1
+ * iLBC storage file format
2
+ * Copyright (c) 2012 Martin Storsjo
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "avformat.h"
22
+#include "internal.h"
23
+
24
+static const char mode20_header[] = "#!iLBC20\n";
25
+static const char mode30_header[] = "#!iLBC30\n";
26
+
27
+static int ilbc_write_header(AVFormatContext *s)
28
+{
29
+    AVIOContext *pb = s->pb;
30
+    AVCodecContext *enc;
31
+
32
+    if (s->nb_streams != 1) {
33
+        av_log(s, AV_LOG_ERROR, "Unsupported number of streams\n");
34
+        return AVERROR(EINVAL);
35
+    }
36
+    enc = s->streams[0]->codec;
37
+
38
+    if (enc->codec_id != CODEC_ID_ILBC) {
39
+        av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
40
+        return AVERROR(EINVAL);
41
+    }
42
+
43
+    if (enc->block_align == 50) {
44
+        avio_write(pb, mode30_header, sizeof(mode30_header) - 1);
45
+    } else if (enc->block_align == 38) {
46
+        avio_write(pb, mode20_header, sizeof(mode20_header) - 1);
47
+    } else {
48
+        av_log(s, AV_LOG_ERROR, "Unsupported mode\n");
49
+        return AVERROR(EINVAL);
50
+    }
51
+    avio_flush(pb);
52
+    return 0;
53
+}
54
+
55
+static int ilbc_write_packet(AVFormatContext *s, AVPacket *pkt)
56
+{
57
+    avio_write(s->pb, pkt->data, pkt->size);
58
+    avio_flush(s->pb);
59
+    return 0;
60
+}
61
+
62
+static int ilbc_probe(AVProbeData *p)
63
+{
64
+    // Only check for "#!iLBC" which matches both formats
65
+    if (!memcmp(p->buf, mode20_header, 6))
66
+        return AVPROBE_SCORE_MAX;
67
+    else
68
+        return 0;
69
+}
70
+
71
+static int ilbc_read_header(AVFormatContext *s)
72
+{
73
+    AVIOContext *pb = s->pb;
74
+    AVStream *st;
75
+    uint8_t header[9];
76
+
77
+    avio_read(pb, header, 9);
78
+
79
+    st = avformat_new_stream(s, NULL);
80
+    if (!st)
81
+        return AVERROR(ENOMEM);
82
+    st->codec->codec_id = CODEC_ID_ILBC;
83
+    st->codec->sample_rate = 8000;
84
+    st->codec->channels = 1;
85
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
86
+    st->start_time = 0;
87
+    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
88
+    if (!memcmp(header, mode20_header, sizeof(mode20_header) - 1)) {
89
+        st->codec->block_align = 38;
90
+        st->codec->bit_rate = 15200;
91
+    } else if (!memcmp(header, mode30_header, sizeof(mode30_header) - 1)) {
92
+        st->codec->block_align = 50;
93
+        st->codec->bit_rate = 13333;
94
+    } else {
95
+        av_log(s, AV_LOG_ERROR, "Unrecognized iLBC file header\n");
96
+        return AVERROR_INVALIDDATA;
97
+    }
98
+
99
+    return 0;
100
+}
101
+
102
+static int ilbc_read_packet(AVFormatContext *s,
103
+                          AVPacket *pkt)
104
+{
105
+    AVCodecContext *enc = s->streams[0]->codec;
106
+    int ret;
107
+
108
+    if ((ret = av_new_packet(pkt, enc->block_align)) < 0)
109
+        return ret;
110
+
111
+    pkt->stream_index = 0;
112
+    pkt->pos = avio_tell(s->pb);
113
+    pkt->duration = enc->block_align == 38 ? 160 : 240;
114
+    if ((ret = avio_read(s->pb, pkt->data, enc->block_align)) != enc->block_align) {
115
+        av_free_packet(pkt);
116
+        return ret < 0 ? ret : AVERROR(EIO);
117
+    }
118
+
119
+    return 0;
120
+}
121
+
122
+AVInputFormat ff_ilbc_demuxer = {
123
+    .name         = "ilbc",
124
+    .long_name    = NULL_IF_CONFIG_SMALL("iLBC storage file format"),
125
+    .read_probe   = ilbc_probe,
126
+    .read_header  = ilbc_read_header,
127
+    .read_packet  = ilbc_read_packet,
128
+    .flags        = AVFMT_GENERIC_INDEX,
129
+};
130
+
131
+AVOutputFormat ff_ilbc_muxer = {
132
+    .name         = "ilbc",
133
+    .long_name    = NULL_IF_CONFIG_SMALL("iLBC storage file format"),
134
+    .mime_type    = "audio/iLBC",
135
+    .extensions   = "lbc",
136
+    .audio_codec  = CODEC_ID_ILBC,
137
+    .write_header = ilbc_write_header,
138
+    .write_packet = ilbc_write_packet,
139
+    .flags        = AVFMT_NOTIMESTAMPS,
140
+};
... ...
@@ -259,6 +259,7 @@ const AVCodecTag ff_codec_movaudio_tags[] = {
259 259
     { CODEC_ID_DVAUDIO,         MKTAG('v', 'd', 'v', 'a') },
260 260
     { CODEC_ID_DVAUDIO,         MKTAG('d', 'v', 'c', 'a') },
261 261
     { CODEC_ID_GSM,             MKTAG('a', 'g', 's', 'm') },
262
+    { CODEC_ID_ILBC,            MKTAG('i', 'l', 'b', 'c') },
262 263
     { CODEC_ID_MACE3,           MKTAG('M', 'A', 'C', '3') },
263 264
     { CODEC_ID_MACE6,           MKTAG('M', 'A', 'C', '6') },
264 265
     { CODEC_ID_MP1,             MKTAG('.', 'm', 'p', '1') },
... ...
@@ -1540,6 +1540,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
1540 1540
     case CODEC_ID_GSM:
1541 1541
     case CODEC_ID_ADPCM_MS:
1542 1542
     case CODEC_ID_ADPCM_IMA_WAV:
1543
+    case CODEC_ID_ILBC:
1543 1544
         st->codec->block_align = sc->bytes_per_frame;
1544 1545
         break;
1545 1546
     case CODEC_ID_ALAC:
... ...
@@ -3371,7 +3371,8 @@ static int mov_write_header(AVFormatContext *s)
3371 3371
                 av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
3372 3372
                 track->audio_vbr = 1;
3373 3373
             }else if(st->codec->codec_id == CODEC_ID_ADPCM_MS ||
3374
-                     st->codec->codec_id == CODEC_ID_ADPCM_IMA_WAV){
3374
+                     st->codec->codec_id == CODEC_ID_ADPCM_IMA_WAV ||
3375
+                     st->codec->codec_id == CODEC_ID_ILBC){
3375 3376
                 if (!st->codec->block_align) {
3376 3377
                     av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
3377 3378
                     goto error;
... ...
@@ -19,8 +19,6 @@
19 19
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 20
  */
21 21
 
22
-//#define USE_SYNCPOINT_SEARCH
23
-
24 22
 #include "libavutil/crc.h"
25 23
 #include "libavutil/intreadwrite.h"
26 24
 #include "libavutil/log.h"
... ...
@@ -2161,92 +2159,6 @@ static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index,
2161 2161
     return AV_NOPTS_VALUE;
2162 2162
 }
2163 2163
 
2164
-#ifdef USE_SYNCPOINT_SEARCH
2165
-
2166
-static int read_seek2(AVFormatContext *s,
2167
-                      int stream_index,
2168
-                      int64_t min_ts,
2169
-                      int64_t target_ts,
2170
-                      int64_t max_ts,
2171
-                      int flags)
2172
-{
2173
-    int64_t pos;
2174
-
2175
-    int64_t ts_ret, ts_adj;
2176
-    int stream_index_gen_search;
2177
-    AVStream *st;
2178
-    AVParserState *backup;
2179
-
2180
-    backup = ff_store_parser_state(s);
2181
-
2182
-    // detect direction of seeking for search purposes
2183
-    flags |= (target_ts - min_ts > (uint64_t)(max_ts - target_ts)) ?
2184
-             AVSEEK_FLAG_BACKWARD : 0;
2185
-
2186
-    if (flags & AVSEEK_FLAG_BYTE) {
2187
-        // use position directly, we will search starting from it
2188
-        pos = target_ts;
2189
-    } else {
2190
-        // search for some position with good timestamp match
2191
-        if (stream_index < 0) {
2192
-            stream_index_gen_search = av_find_default_stream_index(s);
2193
-            if (stream_index_gen_search < 0) {
2194
-                ff_restore_parser_state(s, backup);
2195
-                return -1;
2196
-            }
2197
-
2198
-            st = s->streams[stream_index_gen_search];
2199
-            // timestamp for default must be expressed in AV_TIME_BASE units
2200
-            ts_adj = av_rescale(target_ts,
2201
-                                st->time_base.den,
2202
-                                AV_TIME_BASE * (int64_t)st->time_base.num);
2203
-        } else {
2204
-            ts_adj = target_ts;
2205
-            stream_index_gen_search = stream_index;
2206
-        }
2207
-        pos = ff_gen_search(s, stream_index_gen_search, ts_adj,
2208
-                            0, INT64_MAX, -1,
2209
-                            AV_NOPTS_VALUE,
2210
-                            AV_NOPTS_VALUE,
2211
-                            flags, &ts_ret, mpegts_get_pcr);
2212
-        if (pos < 0) {
2213
-            ff_restore_parser_state(s, backup);
2214
-            return -1;
2215
-        }
2216
-    }
2217
-
2218
-    // search for actual matching keyframe/starting position for all streams
2219
-    if (ff_gen_syncpoint_search(s, stream_index, pos,
2220
-                                min_ts, target_ts, max_ts,
2221
-                                flags) < 0) {
2222
-        ff_restore_parser_state(s, backup);
2223
-        return -1;
2224
-    }
2225
-
2226
-    ff_free_parser_state(s, backup);
2227
-    return 0;
2228
-}
2229
-
2230
-static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
2231
-{
2232
-    int ret;
2233
-    if (flags & AVSEEK_FLAG_BACKWARD) {
2234
-        flags &= ~AVSEEK_FLAG_BACKWARD;
2235
-        ret = read_seek2(s, stream_index, INT64_MIN, target_ts, target_ts, flags);
2236
-        if (ret < 0)
2237
-            // for compatibility reasons, seek to the best-fitting timestamp
2238
-            ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags);
2239
-    } else {
2240
-        ret = read_seek2(s, stream_index, target_ts, target_ts, INT64_MAX, flags);
2241
-        if (ret < 0)
2242
-            // for compatibility reasons, seek to the best-fitting timestamp
2243
-            ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags);
2244
-    }
2245
-    return ret;
2246
-}
2247
-
2248
-#endif
2249
-
2250 2164
 /**************************************************************/
2251 2165
 /* parsing functions - called from other demuxers such as RTP */
2252 2166
 
... ...
@@ -2313,9 +2225,6 @@ AVInputFormat ff_mpegts_demuxer = {
2313 2313
     .read_close     = mpegts_read_close,
2314 2314
     .read_timestamp = mpegts_get_dts,
2315 2315
     .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
2316
-#ifdef USE_SYNCPOINT_SEARCH
2317
-    .read_seek2     = read_seek2,
2318
-#endif
2319 2316
 };
2320 2317
 
2321 2318
 AVInputFormat ff_mpegtsraw_demuxer = {
... ...
@@ -2327,8 +2236,5 @@ AVInputFormat ff_mpegtsraw_demuxer = {
2327 2327
     .read_close     = mpegts_read_close,
2328 2328
     .read_timestamp = mpegts_get_dts,
2329 2329
     .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
2330
-#ifdef USE_SYNCPOINT_SEARCH
2331
-    .read_seek2     = read_seek2,
2332
-#endif
2333 2330
     .priv_class     = &mpegtsraw_class,
2334 2331
 };
... ...
@@ -76,6 +76,7 @@ typedef struct RTMPContext {
76 76
     uint8_t*      flv_data;                   ///< buffer with data for demuxer
77 77
     int           flv_size;                   ///< current buffer size
78 78
     int           flv_off;                    ///< number of bytes read from current buffer
79
+    int           flv_nb_packets;             ///< number of flv packets published
79 80
     RTMPPacket    out_pkt;                    ///< rtmp packet, created from flv a/v or metadata (for output)
80 81
     uint32_t      client_report_size;         ///< number of bytes after which client should report to server
81 82
     uint32_t      bytes_read;                 ///< number of bytes read from server
... ...
@@ -90,6 +91,7 @@ typedef struct RTMPContext {
90 90
     char*         swfurl;                     ///< url of the swf player
91 91
     int           server_bw;                  ///< server bandwidth
92 92
     int           client_buffer_time;         ///< client buffer time in ms
93
+    int           flush_interval;             ///< number of packets flushed in the same request (RTMPT only)
93 94
 } RTMPContext;
94 95
 
95 96
 #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)
1361 1361
             rt->flv_size = 0;
1362 1362
             rt->flv_off = 0;
1363 1363
             rt->flv_header_bytes = 0;
1364
+            rt->flv_nb_packets++;
1364 1365
         }
1365 1366
     } while (buf_temp - buf < size);
1366 1367
 
1368
+    if (rt->flv_nb_packets < rt->flush_interval)
1369
+        return size;
1370
+    rt->flv_nb_packets = 0;
1371
+
1367 1372
     /* set stream into nonblocking mode */
1368 1373
     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
1369 1374
 
... ...
@@ -1404,6 +1411,7 @@ static const AVOption rtmp_options[] = {
1404 1404
     {"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},
1405 1405
     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1406 1406
     {"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},
1407
+    {"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},
1407 1408
     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
1408 1409
     {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
1409 1410
     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},
... ...
@@ -68,6 +68,7 @@ void av_register_rtp_dynamic_payload_handlers(void)
68 68
     ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler);
69 69
     ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler);
70 70
     ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler);
71
+    ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler);
71 72
     ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler);
72 73
     ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler);
73 74
     ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler);
... ...
@@ -45,6 +45,7 @@ extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler;
45 45
 extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler;
46 46
 extern RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler;
47 47
 extern RTPDynamicProtocolHandler ff_h264_dynamic_handler;
48
+extern RTPDynamicProtocolHandler ff_ilbc_dynamic_handler;
48 49
 extern RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler;
49 50
 extern RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler;
50 51
 extern RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler;
51 52
new file mode 100644
... ...
@@ -0,0 +1,73 @@
0
+/*
1
+ * RTP iLBC Depacketizer, RFC 3952
2
+ * Copyright (c) 2012 Martin Storsjo
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "avformat.h"
22
+#include "rtpdec_formats.h"
23
+#include "libavutil/avstring.h"
24
+
25
+static int ilbc_parse_fmtp(AVStream *stream, PayloadContext *data,
26
+                           char *attr, char *value)
27
+{
28
+    if (!strcmp(attr, "mode")) {
29
+        int mode = atoi(value);
30
+        switch (mode) {
31
+        case 20:
32
+            stream->codec->block_align = 38;
33
+            break;
34
+        case 30:
35
+            stream->codec->block_align = 50;
36
+            break;
37
+        default:
38
+            av_log(NULL, AV_LOG_ERROR, "Unsupported iLBC mode %d\n", mode);
39
+            return AVERROR(EINVAL);
40
+        }
41
+    }
42
+    return 0;
43
+}
44
+
45
+static int ilbc_parse_sdp_line(AVFormatContext *s, int st_index,
46
+                               PayloadContext *data, const char *line)
47
+{
48
+    const char *p;
49
+    AVStream *st;
50
+
51
+    if (st_index < 0)
52
+        return 0;
53
+    st = s->streams[st_index];
54
+
55
+    if (av_strstart(line, "fmtp:", &p)) {
56
+        int ret = ff_parse_fmtp(st, data, p, ilbc_parse_fmtp);
57
+        if (ret < 0)
58
+            return ret;
59
+        if (!st->codec->block_align) {
60
+            av_log(s, AV_LOG_ERROR, "No iLBC mode set\n");
61
+            return AVERROR(EINVAL);
62
+        }
63
+    }
64
+    return 0;
65
+}
66
+
67
+RTPDynamicProtocolHandler ff_ilbc_dynamic_handler = {
68
+    .enc_name         = "iLBC",
69
+    .codec_type       = AVMEDIA_TYPE_AUDIO,
70
+    .codec_id         = CODEC_ID_ILBC,
71
+    .parse_sdp_a_line = ilbc_parse_sdp_line,
72
+};
... ...
@@ -74,6 +74,7 @@ static int is_supported(enum CodecID id)
74 74
     case CODEC_ID_VP8:
75 75
     case CODEC_ID_ADPCM_G722:
76 76
     case CODEC_ID_ADPCM_G726:
77
+    case CODEC_ID_ILBC:
77 78
         return 1;
78 79
     default:
79 80
         return 0;
... ...
@@ -187,6 +188,16 @@ static int rtp_write_header(AVFormatContext *s1)
187 187
          * 8000, even if the sample rate is 16000. See RFC 3551. */
188 188
         avpriv_set_pts_info(st, 32, 1, 8000);
189 189
         break;
190
+    case CODEC_ID_ILBC:
191
+        if (st->codec->block_align != 38 && st->codec->block_align != 50) {
192
+            av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n");
193
+            goto fail;
194
+        }
195
+        if (!s->max_frames_per_packet)
196
+            s->max_frames_per_packet = 1;
197
+        s->max_frames_per_packet = FFMIN(s->max_frames_per_packet,
198
+                                         s->max_payload_size / st->codec->block_align);
199
+        goto defaultcase;
190 200
     case CODEC_ID_AMR_NB:
191 201
     case CODEC_ID_AMR_WB:
192 202
         if (!s->max_frames_per_packet)
... ...
@@ -395,6 +406,36 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1,
395 395
     }
396 396
 }
397 397
 
398
+static int rtp_send_ilbc(AVFormatContext *s1, const uint8_t *buf, int size)
399
+{
400
+    RTPMuxContext *s = s1->priv_data;
401
+    AVStream *st = s1->streams[0];
402
+    int frame_duration = av_get_audio_frame_duration(st->codec, 0);
403
+    int frame_size = st->codec->block_align;
404
+    int frames = size / frame_size;
405
+
406
+    while (frames > 0) {
407
+        int n = FFMIN(s->max_frames_per_packet - s->num_frames, frames);
408
+
409
+        if (!s->num_frames) {
410
+            s->buf_ptr = s->buf;
411
+            s->timestamp = s->cur_timestamp;
412
+        }
413
+        memcpy(s->buf_ptr, buf, n * frame_size);
414
+        frames           -= n;
415
+        s->num_frames    += n;
416
+        s->buf_ptr       += n * frame_size;
417
+        buf              += n * frame_size;
418
+        s->cur_timestamp += n * frame_duration;
419
+
420
+        if (s->num_frames == s->max_frames_per_packet) {
421
+            ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 1);
422
+            s->num_frames = 0;
423
+        }
424
+    }
425
+    return 0;
426
+}
427
+
398 428
 static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
399 429
 {
400 430
     RTPMuxContext *s = s1->priv_data;
... ...
@@ -483,6 +524,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
483 483
     case CODEC_ID_VP8:
484 484
         ff_rtp_send_vp8(s1, pkt->data, size);
485 485
         break;
486
+    case CODEC_ID_ILBC:
487
+        rtp_send_ilbc(s1, pkt->data, size);
488
+        break;
486 489
     default:
487 490
         /* better than nothing : send the codec raw data */
488 491
         rtp_send_raw(s1, pkt->data, size);
... ...
@@ -1279,7 +1279,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
1279 1279
                      "%s/UDP;multicast", trans_pref);
1280 1280
         }
1281 1281
         if (s->oformat) {
1282
-            av_strlcat(transport, ";mode=receive", sizeof(transport));
1282
+            av_strlcat(transport, ";mode=record", sizeof(transport));
1283 1283
         } else if (rt->server_type == RTSP_SERVER_REAL ||
1284 1284
                    rt->server_type == RTSP_SERVER_WMS)
1285 1285
             av_strlcat(transport, ";mode=play", sizeof(transport));
... ...
@@ -549,6 +549,12 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c,
549 549
                                          c->sample_rate);
550 550
             break;
551 551
         }
552
+        case CODEC_ID_ILBC:
553
+            av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n"
554
+                                    "a=fmtp:%d mode=%d\r\n",
555
+                                     payload_type, c->sample_rate,
556
+                                     payload_type, c->block_align == 38 ? 20 : 30);
557
+            break;
552 558
         default:
553 559
             /* Nothing special to do here... */
554 560
             break;
... ...
@@ -30,7 +30,7 @@
30 30
 #include "libavutil/avutil.h"
31 31
 
32 32
 #define LIBAVFORMAT_VERSION_MAJOR 54
33
-#define LIBAVFORMAT_VERSION_MINOR  8
33
+#define LIBAVFORMAT_VERSION_MINOR  9
34 34
 #define LIBAVFORMAT_VERSION_MICRO 100
35 35
 
36 36
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
... ...
@@ -1,6 +1,7 @@
1 1
 ;******************************************************************************
2 2
 ;* x86 optimized Format Conversion Utils
3 3
 ;* Copyright (c) 2008 Loren Merritt
4
+;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4 5
 ;*
5 6
 ;* This file is part of Libav.
6 7
 ;*
... ...
@@ -21,9 +22,217 @@
21 21
 
22 22
 %include "x86inc.asm"
23 23
 %include "x86util.asm"
24
+%include "util.asm"
25
+
26
+SECTION_RODATA 32
27
+
28
+pf_s32_inv_scale: times 8 dd 0x30000000
29
+pf_s32_scale:     times 8 dd 0x4f000000
30
+pf_s16_inv_scale: times 4 dd 0x38000000
31
+pf_s16_scale:     times 4 dd 0x47000000
24 32
 
25 33
 SECTION_TEXT
26 34
 
35
+;------------------------------------------------------------------------------
36
+; void ff_conv_s16_to_s32(int32_t *dst, const int16_t *src, int len);
37
+;------------------------------------------------------------------------------
38
+
39
+INIT_XMM sse2
40
+cglobal conv_s16_to_s32, 3,3,3, dst, src, len
41
+    lea      lenq, [2*lend]
42
+    lea      dstq, [dstq+2*lenq]
43
+    add      srcq, lenq
44
+    neg      lenq
45
+.loop:
46
+    mova       m2, [srcq+lenq]
47
+    pxor       m0, m0
48
+    pxor       m1, m1
49
+    punpcklwd  m0, m2
50
+    punpckhwd  m1, m2
51
+    mova  [dstq+2*lenq       ], m0
52
+    mova  [dstq+2*lenq+mmsize], m1
53
+    add      lenq, mmsize
54
+    jl .loop
55
+    REP_RET
56
+
57
+;------------------------------------------------------------------------------
58
+; void ff_conv_s16_to_flt(float *dst, const int16_t *src, int len);
59
+;------------------------------------------------------------------------------
60
+
61
+%macro CONV_S16_TO_FLT 0
62
+cglobal conv_s16_to_flt, 3,3,3, dst, src, len
63
+    lea      lenq, [2*lend]
64
+    add      srcq, lenq
65
+    lea      dstq, [dstq + 2*lenq]
66
+    neg      lenq
67
+    mova       m2, [pf_s16_inv_scale]
68
+    ALIGN 16
69
+.loop:
70
+    mova       m0, [srcq+lenq]
71
+    S16_TO_S32_SX 0, 1
72
+    cvtdq2ps   m0, m0
73
+    cvtdq2ps   m1, m1
74
+    mulps      m0, m2
75
+    mulps      m1, m2
76
+    mova  [dstq+2*lenq       ], m0
77
+    mova  [dstq+2*lenq+mmsize], m1
78
+    add      lenq, mmsize
79
+    jl .loop
80
+    REP_RET
81
+%endmacro
82
+
83
+INIT_XMM sse2
84
+CONV_S16_TO_FLT
85
+INIT_XMM sse4
86
+CONV_S16_TO_FLT
87
+
88
+;------------------------------------------------------------------------------
89
+; void ff_conv_s32_to_s16(int16_t *dst, const int32_t *src, int len);
90
+;------------------------------------------------------------------------------
91
+
92
+%macro CONV_S32_TO_S16 0
93
+cglobal conv_s32_to_s16, 3,3,4, dst, src, len
94
+    lea     lenq, [2*lend]
95
+    lea     srcq, [srcq+2*lenq]
96
+    add     dstq, lenq
97
+    neg     lenq
98
+.loop:
99
+    mova      m0, [srcq+2*lenq         ]
100
+    mova      m1, [srcq+2*lenq+  mmsize]
101
+    mova      m2, [srcq+2*lenq+2*mmsize]
102
+    mova      m3, [srcq+2*lenq+3*mmsize]
103
+    psrad     m0, 16
104
+    psrad     m1, 16
105
+    psrad     m2, 16
106
+    psrad     m3, 16
107
+    packssdw  m0, m1
108
+    packssdw  m2, m3
109
+    mova  [dstq+lenq       ], m0
110
+    mova  [dstq+lenq+mmsize], m2
111
+    add     lenq, mmsize*2
112
+    jl .loop
113
+%if mmsize == 8
114
+    emms
115
+    RET
116
+%else
117
+    REP_RET
118
+%endif
119
+%endmacro
120
+
121
+INIT_MMX mmx
122
+CONV_S32_TO_S16
123
+INIT_XMM sse2
124
+CONV_S32_TO_S16
125
+
126
+;------------------------------------------------------------------------------
127
+; void ff_conv_s32_to_flt(float *dst, const int32_t *src, int len);
128
+;------------------------------------------------------------------------------
129
+
130
+%macro CONV_S32_TO_FLT 0
131
+cglobal conv_s32_to_flt, 3,3,3, dst, src, len
132
+    lea     lenq, [4*lend]
133
+    add     srcq, lenq
134
+    add     dstq, lenq
135
+    neg     lenq
136
+    mova      m0, [pf_s32_inv_scale]
137
+    ALIGN 16
138
+.loop:
139
+    cvtdq2ps  m1, [srcq+lenq       ]
140
+    cvtdq2ps  m2, [srcq+lenq+mmsize]
141
+    mulps     m1, m1, m0
142
+    mulps     m2, m2, m0
143
+    mova  [dstq+lenq       ], m1
144
+    mova  [dstq+lenq+mmsize], m2
145
+    add     lenq, mmsize*2
146
+    jl .loop
147
+%if mmsize == 32
148
+    vzeroupper
149
+    RET
150
+%else
151
+    REP_RET
152
+%endif
153
+%endmacro
154
+
155
+INIT_XMM sse2
156
+CONV_S32_TO_FLT
157
+%if HAVE_AVX
158
+INIT_YMM avx
159
+CONV_S32_TO_FLT
160
+%endif
161
+
162
+;------------------------------------------------------------------------------
163
+; void ff_conv_flt_to_s16(int16_t *dst, const float *src, int len);
164
+;------------------------------------------------------------------------------
165
+
166
+INIT_XMM sse2
167
+cglobal conv_flt_to_s16, 3,3,5, dst, src, len
168
+    lea     lenq, [2*lend]
169
+    lea     srcq, [srcq+2*lenq]
170
+    add     dstq, lenq
171
+    neg     lenq
172
+    mova      m4, [pf_s16_scale]
173
+.loop:
174
+    mova      m0, [srcq+2*lenq         ]
175
+    mova      m1, [srcq+2*lenq+1*mmsize]
176
+    mova      m2, [srcq+2*lenq+2*mmsize]
177
+    mova      m3, [srcq+2*lenq+3*mmsize]
178
+    mulps     m0, m4
179
+    mulps     m1, m4
180
+    mulps     m2, m4
181
+    mulps     m3, m4
182
+    cvtps2dq  m0, m0
183
+    cvtps2dq  m1, m1
184
+    cvtps2dq  m2, m2
185
+    cvtps2dq  m3, m3
186
+    packssdw  m0, m1
187
+    packssdw  m2, m3
188
+    mova  [dstq+lenq       ], m0
189
+    mova  [dstq+lenq+mmsize], m2
190
+    add     lenq, mmsize*2
191
+    jl .loop
192
+    REP_RET
193
+
194
+;------------------------------------------------------------------------------
195
+; void ff_conv_flt_to_s32(int32_t *dst, const float *src, int len);
196
+;------------------------------------------------------------------------------
197
+
198
+%macro CONV_FLT_TO_S32 0
199
+cglobal conv_flt_to_s32, 3,3,5, dst, src, len
200
+    lea     lenq, [lend*4]
201
+    add     srcq, lenq
202
+    add     dstq, lenq
203
+    neg     lenq
204
+    mova      m4, [pf_s32_scale]
205
+.loop:
206
+    mulps     m0, m4, [srcq+lenq         ]
207
+    mulps     m1, m4, [srcq+lenq+1*mmsize]
208
+    mulps     m2, m4, [srcq+lenq+2*mmsize]
209
+    mulps     m3, m4, [srcq+lenq+3*mmsize]
210
+    cvtps2dq  m0, m0
211
+    cvtps2dq  m1, m1
212
+    cvtps2dq  m2, m2
213
+    cvtps2dq  m3, m3
214
+    mova  [dstq+lenq         ], m0
215
+    mova  [dstq+lenq+1*mmsize], m1
216
+    mova  [dstq+lenq+2*mmsize], m2
217
+    mova  [dstq+lenq+3*mmsize], m3
218
+    add     lenq, mmsize*4
219
+    jl .loop
220
+%if mmsize == 32
221
+    vzeroupper
222
+    RET
223
+%else
224
+    REP_RET
225
+%endif
226
+%endmacro
227
+
228
+INIT_XMM sse2
229
+CONV_FLT_TO_S32
230
+%if HAVE_AVX
231
+INIT_YMM avx
232
+CONV_FLT_TO_S32
233
+%endif
234
+
27 235
 ;-----------------------------------------------------------------------------
28 236
 ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len,
29 237
 ;                              int channels);
... ...
@@ -22,6 +22,22 @@
22 22
 #include "libavutil/cpu.h"
23 23
 #include "libavresample/audio_convert.h"
24 24
 
25
+extern void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len);
26
+
27
+extern void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len);
28
+extern void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len);
29
+
30
+extern void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len);
31
+extern void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len);
32
+
33
+extern void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len);
34
+extern void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len);
35
+
36
+extern void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len);
37
+
38
+extern void ff_conv_flt_to_s32_sse2(int32_t *dst, const float *src, int len);
39
+extern void ff_conv_flt_to_s32_avx (int32_t *dst, const float *src, int len);
40
+
25 41
 extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len);
26 42
 extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len);
27 43
 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)
32 32
     int mm_flags = av_get_cpu_flags();
33 33
 
34 34
     if (mm_flags & AV_CPU_FLAG_MMX && HAVE_MMX) {
35
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
36
+                                  0, 1, 8, "MMX", ff_conv_s32_to_s16_mmx);
35 37
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
36 38
                                   6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx);
37 39
     }
... ...
@@ -43,5 +61,31 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac)
43 43
         ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
44 44
                                   6, 16, 4, "AVX", ff_conv_fltp_to_flt_6ch_avx);
45 45
     }
46
+    if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) {
47
+        if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) {
48
+            ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32,
49
+                                      0, 16, 16, "SSE2", ff_conv_s32_to_s16_sse2);
50
+        }
51
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16,
52
+                                  0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2);
53
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
54
+                                  0, 16, 8, "SSE2", ff_conv_s16_to_flt_sse2);
55
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
56
+                                  0, 16, 8, "SSE2", ff_conv_s32_to_flt_sse2);
57
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT,
58
+                                  0, 16, 16, "SSE2", ff_conv_flt_to_s16_sse2);
59
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
60
+                                  0, 16, 16, "SSE2", ff_conv_flt_to_s32_sse2);
61
+    }
62
+    if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) {
63
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16,
64
+                                  0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4);
65
+    }
66
+    if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) {
67
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32,
68
+                                  0, 32, 16, "AVX", ff_conv_s32_to_flt_avx);
69
+        ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT,
70
+                                  0, 32, 32, "AVX", ff_conv_flt_to_s32_avx);
71
+    }
46 72
 #endif
47 73
 }
... ...
@@ -26,7 +26,11 @@
26 26
 
27 27
 void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, int len);
28 28
 
29
+void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul,
30
+                                int len);
31
+
29 32
 void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp)
30 33
 {
31 34
     fdsp->vector_fmul = ff_vector_fmul_neon;
35
+    fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon;
32 36
 }
... ...
@@ -62,3 +62,51 @@ function ff_vector_fmul_neon, export=1
62 62
 3:      vst1.32         {d16-d19},[r0,:128]!
63 63
         bx              lr
64 64
 endfunc
65
+
66
+function ff_vector_fmac_scalar_neon, export=1
67
+VFP     len .req r2
68
+VFP     acc .req r3
69
+NOVFP   len .req r3
70
+NOVFP   acc .req r2
71
+VFP     vdup.32         q15, d0[0]
72
+NOVFP   vdup.32         q15, r2
73
+        bics            r12, len, #15
74
+        mov             acc, r0
75
+        beq             3f
76
+        vld1.32         {q0},     [r1,:128]!
77
+        vld1.32         {q8},     [acc,:128]!
78
+        vld1.32         {q1},     [r1,:128]!
79
+        vld1.32         {q9},     [acc,:128]!
80
+1:      vmla.f32        q8,  q0,  q15
81
+        vld1.32         {q2},     [r1,:128]!
82
+        vld1.32         {q10},    [acc,:128]!
83
+        vmla.f32        q9,  q1,  q15
84
+        vld1.32         {q3},     [r1,:128]!
85
+        vld1.32         {q11},    [acc,:128]!
86
+        vmla.f32        q10, q2,  q15
87
+        vst1.32         {q8},     [r0,:128]!
88
+        vmla.f32        q11, q3,  q15
89
+        vst1.32         {q9},     [r0,:128]!
90
+        subs            r12, r12, #16
91
+        beq             2f
92
+        vld1.32         {q0},     [r1,:128]!
93
+        vld1.32         {q8},     [acc,:128]!
94
+        vst1.32         {q10},    [r0,:128]!
95
+        vld1.32         {q1},     [r1,:128]!
96
+        vld1.32         {q9},     [acc,:128]!
97
+        vst1.32         {q11},    [r0,:128]!
98
+        b               1b
99
+2:      vst1.32         {q10},    [r0,:128]!
100
+        vst1.32         {q11},    [r0,:128]!
101
+        ands            len, len, #15
102
+        it              eq
103
+        bxeq            lr
104
+3:      vld1.32         {q0},     [r1,:128]!
105
+        vld1.32         {q8},     [acc,:128]!
106
+        vmla.f32        q8,  q0,  q15
107
+        vst1.32         {q8},     [r0,:128]!
108
+        subs            len, len, #4
109
+        bgt             3b
110
+        bx              lr
111
+        .unreq          len
112
+endfunc
... ...
@@ -31,9 +31,18 @@ static void vector_fmul_c(float *dst, const float *src0, const float *src1,
31 31
         dst[i] = src0[i] * src1[i];
32 32
 }
33 33
 
34
+static void vector_fmac_scalar_c(float *dst, const float *src, float mul,
35
+                                 int len)
36
+{
37
+    int i;
38
+    for (i = 0; i < len; i++)
39
+        dst[i] += src[i] * mul;
40
+}
41
+
34 42
 void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
35 43
 {
36 44
     fdsp->vector_fmul = vector_fmul_c;
45
+    fdsp->vector_fmac_scalar = vector_fmac_scalar_c;
37 46
 
38 47
 #if ARCH_ARM
39 48
     ff_float_dsp_init_arm(fdsp);
... ...
@@ -35,6 +35,22 @@ typedef struct AVFloatDSPContext {
35 35
      */
36 36
     void (*vector_fmul)(float *dst, const float *src0, const float *src1,
37 37
                         int len);
38
+
39
+    /**
40
+     * Multiply a vector of floats by a scalar float and add to
41
+     * destination vector.  Source and destination vectors must
42
+     * overlap exactly or not at all.
43
+     *
44
+     * @param dst result vector
45
+     *            constraints: 32-byte aligned
46
+     * @param src input vector
47
+     *            constraints: 32-byte aligned
48
+     * @param mul scalar value
49
+     * @param len length of vector
50
+     *            constraints: multiple of 16
51
+     */
52
+    void (*vector_fmac_scalar)(float *dst, const float *src, float mul,
53
+                               int len);
38 54
 } AVFloatDSPContext;
39 55
 
40 56
 /**
... ...
@@ -94,6 +94,8 @@ void *av_malloc(size_t size)
94 94
     if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
95 95
     if (posix_memalign(&ptr,ALIGN,size))
96 96
         ptr = NULL;
97
+#elif HAVE_ALIGNED_MALLOC
98
+    ptr = _aligned_malloc(size, ALIGN);
97 99
 #elif HAVE_MEMALIGN
98 100
     ptr = memalign(ALIGN,size);
99 101
     /* Why 64?
... ...
@@ -145,6 +147,8 @@ void *av_realloc(void *ptr, size_t size)
145 145
     ptr= realloc((char*)ptr - diff, size + diff);
146 146
     if(ptr) ptr = (char*)ptr + diff;
147 147
     return ptr;
148
+#elif HAVE_ALIGNED_MALLOC
149
+    return _aligned_realloc(ptr, size + !size, ALIGN);
148 150
 #else
149 151
     return realloc(ptr, size + !size);
150 152
 #endif
... ...
@@ -170,6 +174,8 @@ void av_free(void *ptr)
170 170
 #if CONFIG_MEMALIGN_HACK
171 171
     if (ptr)
172 172
         free((char*)ptr - ((char*)ptr)[-1]);
173
+#elif HAVE_ALIGNED_MALLOC
174
+    _aligned_free(ptr);
173 175
 #else
174 176
     free(ptr);
175 177
 #endif
... ...
@@ -21,6 +21,7 @@
21 21
 ;******************************************************************************
22 22
 
23 23
 %include "x86inc.asm"
24
+%include "x86util.asm"
24 25
 
25 26
 SECTION .text
26 27
 
... ...
@@ -55,3 +56,49 @@ VECTOR_FMUL
55 55
 INIT_YMM avx
56 56
 VECTOR_FMUL
57 57
 %endif
58
+
59
+;------------------------------------------------------------------------------
60
+; void ff_vector_fmac_scalar(float *dst, const float *src, float mul, int len)
61
+;------------------------------------------------------------------------------
62
+
63
+%macro VECTOR_FMAC_SCALAR 0
64
+%if UNIX64
65
+cglobal vector_fmac_scalar, 3,3,3, dst, src, len
66
+%else
67
+cglobal vector_fmac_scalar, 4,4,3, dst, src, mul, len
68
+%endif
69
+%if WIN64
70
+    SWAP 0, 2
71
+%endif
72
+%if ARCH_X86_32
73
+    VBROADCASTSS m0, mulm
74
+%else
75
+    shufps     xmm0, xmm0, 0
76
+%if cpuflag(avx)
77
+    vinsertf128  m0, m0, xmm0, 1
78
+%endif
79
+%endif
80
+    lea    lenq, [lend*4-2*mmsize]
81
+.loop
82
+    mulps    m1, m0, [srcq+lenq       ]
83
+    mulps    m2, m0, [srcq+lenq+mmsize]
84
+    addps    m1, m1, [dstq+lenq       ]
85
+    addps    m2, m2, [dstq+lenq+mmsize]
86
+    mova  [dstq+lenq       ], m1
87
+    mova  [dstq+lenq+mmsize], m2
88
+    sub    lenq, 2*mmsize
89
+    jge .loop
90
+%if mmsize == 32
91
+    vzeroupper
92
+    RET
93
+%else
94
+    REP_RET
95
+%endif
96
+%endmacro
97
+
98
+INIT_XMM sse
99
+VECTOR_FMAC_SCALAR
100
+%if HAVE_AVX
101
+INIT_YMM avx
102
+VECTOR_FMAC_SCALAR
103
+%endif
... ...
@@ -26,6 +26,11 @@ extern void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
26 26
 extern void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1,
27 27
                                int len);
28 28
 
29
+extern void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul,
30
+                                      int len);
31
+extern void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul,
32
+                                      int len);
33
+
29 34
 void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
30 35
 {
31 36
 #if HAVE_YASM
... ...
@@ -33,9 +38,11 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
33 33
 
34 34
     if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) {
35 35
         fdsp->vector_fmul = ff_vector_fmul_sse;
36
+        fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse;
36 37
     }
37 38
     if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) {
38 39
         fdsp->vector_fmul = ff_vector_fmul_avx;
40
+        fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx;
39 41
     }
40 42
 #endif
41 43
 }