Browse code

Merge remote-tracking branch 'qatar/master'

* qatar/master:
mss3: use standard zigzag table
mss3: split DSP functions that are used in MTS2(MSS4) into separate file
motion-test: do not use getopt()
tcp: add initial timeout limit for incoming connections
configure: Change the rdtsc check to a linker check
avconv: propagate fatal errors from lavfi.
lavfi: add error handling to filter_samples().
fate-run: make avconv() properly deal with multiple inputs.
asplit: don't leak the input buffer.
af_resample: fix request_frame() behavior.
af_asyncts: fix request_frame() behavior.
libx264: support aspect ratio switching
matroskadec: honor error_recognition when encountering unknown elements.
lavr: resampling: add support for s32p, fltp, and dblp internal sample formats
lavr: resampling: add filter type and Kaiser window beta to AVOptions
lavr: Use AV_SAMPLE_FMT_NONE to auto-select the internal sample format
lavr: mix: validate internal sample format in ff_audio_mix_init()

Conflicts:
ffmpeg.c
ffplay.c
libavcodec/libx264.c
libavfilter/audio.c
libavfilter/split.c
libavformat/tcp.c
tests/fate-run.sh

Merged-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2012/07/10 05:10:38
Showing 45 changed files
... ...
@@ -327,7 +327,7 @@ OBJS-$(CONFIG_MSMPEG4V3_ENCODER)       += msmpeg4.o msmpeg4enc.o msmpeg4data.o \
327 327
                                           h263dec.o h263.o ituh263dec.o        \
328 328
                                           mpeg4videodec.o
329 329
 OBJS-$(CONFIG_MSRLE_DECODER)           += msrle.o msrledec.o
330
-OBJS-$(CONFIG_MSA1_DECODER)            += mss3.o
330
+OBJS-$(CONFIG_MSA1_DECODER)            += mss3.o mss34dsp.o
331 331
 OBJS-$(CONFIG_MSS1_DECODER)            += mss1.o
332 332
 OBJS-$(CONFIG_MSVIDEO1_DECODER)        += msvideo1.o
333 333
 OBJS-$(CONFIG_MSVIDEO1_ENCODER)        += msvideo1enc.o elbg.o
... ...
@@ -175,10 +175,10 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
175 175
             x4->params.b_tff = frame->top_field_first;
176 176
             x264_encoder_reconfig(x4->enc, &x4->params);
177 177
         }
178
-        if (x4->params.vui.i_sar_height != ctx->sample_aspect_ratio.den
179
-         || x4->params.vui.i_sar_width != ctx->sample_aspect_ratio.num) {
178
+        if (x4->params.vui.i_sar_height != ctx->sample_aspect_ratio.den ||
179
+            x4->params.vui.i_sar_width  != ctx->sample_aspect_ratio.num) {
180 180
             x4->params.vui.i_sar_height = ctx->sample_aspect_ratio.den;
181
-            x4->params.vui.i_sar_width = ctx->sample_aspect_ratio.num;
181
+            x4->params.vui.i_sar_width  = ctx->sample_aspect_ratio.num;
182 182
             x264_encoder_reconfig(x4->enc, &x4->params);
183 183
         }
184 184
     }
... ...
@@ -119,15 +119,9 @@ int main(int argc, char **argv)
119 119
     int flags[2] = { AV_CPU_FLAG_MMX, AV_CPU_FLAG_MMX2 };
120 120
     int flags_size = HAVE_MMX2 ? 2 : 1;
121 121
 
122
-    for(;;) {
123
-        c = getopt(argc, argv, "h");
124
-        if (c == -1)
125
-            break;
126
-        switch(c) {
127
-        case 'h':
128
-            help();
129
-            return 1;
130
-        }
122
+    if (argc > 1) {
123
+        help();
124
+        return 1;
131 125
     }
132 126
 
133 127
     printf("ffmpeg motion test\n");
... ...
@@ -26,6 +26,8 @@
26 26
 
27 27
 #include "avcodec.h"
28 28
 #include "bytestream.h"
29
+#include "dsputil.h"
30
+#include "mss34dsp.h"
29 31
 
30 32
 #define HEADER_SIZE 27
31 33
 
... ...
@@ -119,39 +121,6 @@ typedef struct MSS3Context {
119 119
     int              hblock[16 * 16];
120 120
 } MSS3Context;
121 121
 
122
-static const uint8_t mss3_luma_quant[64] = {
123
-    16,  11,  10,  16,  24,  40,  51,  61,
124
-    12,  12,  14,  19,  26,  58,  60,  55,
125
-    14,  13,  16,  24,  40,  57,  69,  56,
126
-    14,  17,  22,  29,  51,  87,  80,  62,
127
-    18,  22,  37,  56,  68, 109, 103,  77,
128
-    24,  35,  55,  64,  81, 104, 113,  92,
129
-    49,  64,  78,  87, 103, 121, 120, 101,
130
-    72,  92,  95,  98, 112, 100, 103,  99
131
-};
132
-
133
-static const uint8_t mss3_chroma_quant[64] = {
134
-    17, 18, 24, 47, 99, 99, 99, 99,
135
-    18, 21, 26, 66, 99, 99, 99, 99,
136
-    24, 26, 56, 99, 99, 99, 99, 99,
137
-    47, 66, 99, 99, 99, 99, 99, 99,
138
-    99, 99, 99, 99, 99, 99, 99, 99,
139
-    99, 99, 99, 99, 99, 99, 99, 99,
140
-    99, 99, 99, 99, 99, 99, 99, 99,
141
-    99, 99, 99, 99, 99, 99, 99, 99
142
-};
143
-
144
-static const uint8_t zigzag_scan[64] = {
145
-    0,   1,  8, 16,  9,  2,  3, 10,
146
-    17, 24, 32, 25, 18, 11,  4,  5,
147
-    12, 19, 26, 33, 40, 48, 41, 34,
148
-    27, 20, 13,  6,  7, 14, 21, 28,
149
-    35, 42, 49, 56, 57, 50, 43, 36,
150
-    29, 22, 15, 23, 30, 37, 44, 51,
151
-    58, 59, 52, 45, 38, 31, 39, 46,
152
-    53, 60, 61, 54, 47, 55, 62, 63
153
-};
154
-
155 122
 
156 123
 static void model2_reset(Model2 *m)
157 124
 {
... ...
@@ -578,7 +547,7 @@ static int decode_dct(RangeCoder *c, DCTBlockCoder *bc, int *block,
578 578
         if (!sign)
579 579
             val = -val;
580 580
 
581
-        zz_pos = zigzag_scan[pos];
581
+        zz_pos = ff_zigzag_direct[pos];
582 582
         block[zz_pos] = val * bc->qmat[zz_pos];
583 583
         pos++;
584 584
     }
... ...
@@ -586,58 +555,6 @@ static int decode_dct(RangeCoder *c, DCTBlockCoder *bc, int *block,
586 586
     return pos == 64 ? 0 : -1;
587 587
 }
588 588
 
589
-#define DCT_TEMPLATE(blk, step, SOP, shift)                         \
590
-    const int t0 = -39409 * blk[7 * step] -  58980 * blk[1 * step]; \
591
-    const int t1 =  39410 * blk[1 * step] -  58980 * blk[7 * step]; \
592
-    const int t2 = -33410 * blk[5 * step] - 167963 * blk[3 * step]; \
593
-    const int t3 =  33410 * blk[3 * step] - 167963 * blk[5 * step]; \
594
-    const int t4 =          blk[3 * step] +          blk[7 * step]; \
595
-    const int t5 =          blk[1 * step] +          blk[5 * step]; \
596
-    const int t6 =  77062 * t4            +  51491 * t5;            \
597
-    const int t7 =  77062 * t5            -  51491 * t4;            \
598
-    const int t8 =  35470 * blk[2 * step] -  85623 * blk[6 * step]; \
599
-    const int t9 =  35470 * blk[6 * step] +  85623 * blk[2 * step]; \
600
-    const int tA = SOP(blk[0 * step] - blk[4 * step]);              \
601
-    const int tB = SOP(blk[0 * step] + blk[4 * step]);              \
602
-                                                                    \
603
-    blk[0 * step] = (  t1 + t6  + t9 + tB) >> shift;                \
604
-    blk[1 * step] = (  t3 + t7  + t8 + tA) >> shift;                \
605
-    blk[2 * step] = (  t2 + t6  - t8 + tA) >> shift;                \
606
-    blk[3 * step] = (  t0 + t7  - t9 + tB) >> shift;                \
607
-    blk[4 * step] = (-(t0 + t7) - t9 + tB) >> shift;                \
608
-    blk[5 * step] = (-(t2 + t6) - t8 + tA) >> shift;                \
609
-    blk[6 * step] = (-(t3 + t7) + t8 + tA) >> shift;                \
610
-    blk[7 * step] = (-(t1 + t6) + t9 + tB) >> shift;                \
611
-
612
-#define SOP_ROW(a) ((a) << 16) + 0x2000
613
-#define SOP_COL(a) ((a + 32) << 16)
614
-
615
-static void dct_put(uint8_t *dst, int stride, int *block)
616
-{
617
-    int i, j;
618
-    int *ptr;
619
-
620
-    ptr = block;
621
-    for (i = 0; i < 8; i++) {
622
-        DCT_TEMPLATE(ptr, 1, SOP_ROW, 13);
623
-        ptr += 8;
624
-    }
625
-
626
-    ptr = block;
627
-    for (i = 0; i < 8; i++) {
628
-        DCT_TEMPLATE(ptr, 8, SOP_COL, 22);
629
-        ptr++;
630
-    }
631
-
632
-    ptr = block;
633
-    for (j = 0; j < 8; j++) {
634
-        for (i = 0; i < 8; i++)
635
-            dst[i] = av_clip_uint8(ptr[i] + 128);
636
-        dst += stride;
637
-        ptr += 8;
638
-    }
639
-}
640
-
641 589
 static void decode_dct_block(RangeCoder *c, DCTBlockCoder *bc,
642 590
                              uint8_t *dst, int stride, int block_size,
643 591
                              int *block, int mb_x, int mb_y)
... ...
@@ -655,7 +572,7 @@ static void decode_dct_block(RangeCoder *c, DCTBlockCoder *bc,
655 655
                 c->got_error = 1;
656 656
                 return;
657 657
             }
658
-            dct_put(dst + i * 8, stride, block);
658
+            ff_mss34_dct_put(dst + i * 8, stride, block);
659 659
         }
660 660
         dst += 8 * stride;
661 661
     }
... ...
@@ -702,14 +619,6 @@ static void decode_haar_block(RangeCoder *c, HaarBlockCoder *hc,
702 702
     }
703 703
 }
704 704
 
705
-static void gen_quant_mat(uint16_t *qmat, const uint8_t *ref, float scale)
706
-{
707
-    int i;
708
-
709
-    for (i = 0; i < 64; i++)
710
-        qmat[i] = (uint16_t)(ref[i] * scale + 50.0) / 100;
711
-}
712
-
713 705
 static void reset_coders(MSS3Context *ctx, int quality)
714 706
 {
715 707
     int i, j;
... ...
@@ -726,15 +635,8 @@ static void reset_coders(MSS3Context *ctx, int quality)
726 726
         for (j = 0; j < 125; j++)
727 727
             model_reset(&ctx->image_coder[i].vq_model[j]);
728 728
         if (ctx->dct_coder[i].quality != quality) {
729
-            float scale;
730 729
             ctx->dct_coder[i].quality = quality;
731
-            if (quality > 50)
732
-                scale = 200.0f - 2 * quality;
733
-            else
734
-                scale = 5000.0f / quality;
735
-            gen_quant_mat(ctx->dct_coder[i].qmat,
736
-                          i ? mss3_chroma_quant : mss3_luma_quant,
737
-                          scale);
730
+            ff_mss34_gen_quant_mat(ctx->dct_coder[i].qmat, quality, !i);
738 731
         }
739 732
         memset(ctx->dct_coder[i].prev_dc, 0,
740 733
                sizeof(*ctx->dct_coder[i].prev_dc) *
741 734
new file mode 100644
... ...
@@ -0,0 +1,114 @@
0
+/*
1
+ * Common stuff for some Microsoft Screen codecs
2
+ * Copyright (C) 2012 Konstantin Shishkov
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 <stdint.h>
22
+#include "libavutil/common.h"
23
+#include "mss34dsp.h"
24
+
25
+static const uint8_t luma_quant[64] = {
26
+    16,  11,  10,  16,  24,  40,  51,  61,
27
+    12,  12,  14,  19,  26,  58,  60,  55,
28
+    14,  13,  16,  24,  40,  57,  69,  56,
29
+    14,  17,  22,  29,  51,  87,  80,  62,
30
+    18,  22,  37,  56,  68, 109, 103,  77,
31
+    24,  35,  55,  64,  81, 104, 113,  92,
32
+    49,  64,  78,  87, 103, 121, 120, 101,
33
+    72,  92,  95,  98, 112, 100, 103,  99
34
+};
35
+
36
+static const uint8_t chroma_quant[64] = {
37
+    17, 18, 24, 47, 99, 99, 99, 99,
38
+    18, 21, 26, 66, 99, 99, 99, 99,
39
+    24, 26, 56, 99, 99, 99, 99, 99,
40
+    47, 66, 99, 99, 99, 99, 99, 99,
41
+    99, 99, 99, 99, 99, 99, 99, 99,
42
+    99, 99, 99, 99, 99, 99, 99, 99,
43
+    99, 99, 99, 99, 99, 99, 99, 99,
44
+    99, 99, 99, 99, 99, 99, 99, 99
45
+};
46
+
47
+void ff_mss34_gen_quant_mat(uint16_t *qmat, int quality, int luma)
48
+{
49
+    int i;
50
+    const uint8_t *qsrc = luma ? luma_quant : chroma_quant;
51
+
52
+    if (quality >= 50) {
53
+        int scale = 200 - 2 * quality;
54
+
55
+        for (i = 0; i < 64; i++)
56
+            qmat[i] = (qsrc[i] * scale + 50) / 100;
57
+    } else {
58
+        for (i = 0; i < 64; i++)
59
+            qmat[i] = (5000 * qsrc[i] / quality + 50) / 100;
60
+    }
61
+}
62
+
63
+#define DCT_TEMPLATE(blk, step, SOP, shift)                         \
64
+    const int t0 = -39409 * blk[7 * step] -  58980 * blk[1 * step]; \
65
+    const int t1 =  39410 * blk[1 * step] -  58980 * blk[7 * step]; \
66
+    const int t2 = -33410 * blk[5 * step] - 167963 * blk[3 * step]; \
67
+    const int t3 =  33410 * blk[3 * step] - 167963 * blk[5 * step]; \
68
+    const int t4 =          blk[3 * step] +          blk[7 * step]; \
69
+    const int t5 =          blk[1 * step] +          blk[5 * step]; \
70
+    const int t6 =  77062 * t4            +  51491 * t5;            \
71
+    const int t7 =  77062 * t5            -  51491 * t4;            \
72
+    const int t8 =  35470 * blk[2 * step] -  85623 * blk[6 * step]; \
73
+    const int t9 =  35470 * blk[6 * step] +  85623 * blk[2 * step]; \
74
+    const int tA = SOP(blk[0 * step] - blk[4 * step]);              \
75
+    const int tB = SOP(blk[0 * step] + blk[4 * step]);              \
76
+                                                                    \
77
+    blk[0 * step] = (  t1 + t6  + t9 + tB) >> shift;                \
78
+    blk[1 * step] = (  t3 + t7  + t8 + tA) >> shift;                \
79
+    blk[2 * step] = (  t2 + t6  - t8 + tA) >> shift;                \
80
+    blk[3 * step] = (  t0 + t7  - t9 + tB) >> shift;                \
81
+    blk[4 * step] = (-(t0 + t7) - t9 + tB) >> shift;                \
82
+    blk[5 * step] = (-(t2 + t6) - t8 + tA) >> shift;                \
83
+    blk[6 * step] = (-(t3 + t7) + t8 + tA) >> shift;                \
84
+    blk[7 * step] = (-(t1 + t6) + t9 + tB) >> shift;                \
85
+
86
+#define SOP_ROW(a) ((a) << 16) + 0x2000
87
+#define SOP_COL(a) ((a + 32) << 16)
88
+
89
+void ff_mss34_dct_put(uint8_t *dst, int stride, int *block)
90
+{
91
+    int i, j;
92
+    int *ptr;
93
+
94
+    ptr = block;
95
+    for (i = 0; i < 8; i++) {
96
+        DCT_TEMPLATE(ptr, 1, SOP_ROW, 13);
97
+        ptr += 8;
98
+    }
99
+
100
+    ptr = block;
101
+    for (i = 0; i < 8; i++) {
102
+        DCT_TEMPLATE(ptr, 8, SOP_COL, 22);
103
+        ptr++;
104
+    }
105
+
106
+    ptr = block;
107
+    for (j = 0; j < 8; j++) {
108
+        for (i = 0; i < 8; i++)
109
+            dst[i] = av_clip_uint8(ptr[i] + 128);
110
+        dst += stride;
111
+        ptr += 8;
112
+    }
113
+}
0 114
new file mode 100644
... ...
@@ -0,0 +1,45 @@
0
+/*
1
+ * Common stuff for some Microsoft Screen codecs
2
+ * Copyright (C) 2012 Konstantin Shishkov
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
+#ifndef AVCODEC_MSS34DSP_H
22
+#define AVCODEC_MSS34DSP_H
23
+
24
+#include <stdint.h>
25
+
26
+/**
27
+ * Generate quantisation matrix for given quality.
28
+ *
29
+ * @param qmat    destination matrix
30
+ * @param quality quality setting (1-100)
31
+ * @param luma    generate quantisation matrix for luma or chroma
32
+ */
33
+void ff_mss34_gen_quant_mat(uint16_t *qmat, int quality, int luma);
34
+
35
+/**
36
+ * Transform and output DCT block.
37
+ *
38
+ * @param dst     output plane
39
+ * @param stride  output plane stride
40
+ * @param block   block to transform and output
41
+ */
42
+void ff_mss34_dct_put(uint8_t *dst, int stride, int *block);
43
+
44
+#endif /* AVCODEC_MSS34DSP_H */
... ...
@@ -135,12 +135,13 @@ static int config_output(AVFilterLink *outlink)
135 135
     return 0;
136 136
 }
137 137
 
138
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
138
+static int  filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
139 139
 {
140 140
     AConvertContext *aconvert = inlink->dst->priv;
141 141
     const int n = insamplesref->audio->nb_samples;
142 142
     AVFilterLink *const outlink = inlink->dst->outputs[0];
143 143
     AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n);
144
+    int ret;
144 145
 
145 146
     swr_convert(aconvert->swr, outsamplesref->data, n,
146 147
                         (void *)insamplesref->data, n);
... ...
@@ -148,8 +149,9 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref
148 148
     avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
149 149
     outsamplesref->audio->channel_layout = outlink->channel_layout;
150 150
 
151
-    ff_filter_samples(outlink, outsamplesref);
151
+    ret = ff_filter_samples(outlink, outsamplesref);
152 152
     avfilter_unref_buffer(insamplesref);
153
+    return ret;
153 154
 }
154 155
 
155 156
 AVFilter avfilter_af_aconvert = {
... ...
@@ -212,7 +212,7 @@ static inline void copy_samples(int nb_inputs, struct amerge_input in[],
212 212
     }
213 213
 }
214 214
 
215
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
215
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
216 216
 {
217 217
     AVFilterContext *ctx = inlink->dst;
218 218
     AMergeContext *am = ctx->priv;
... ...
@@ -232,7 +232,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
232 232
     for (i = 1; i < am->nb_inputs; i++)
233 233
         nb_samples = FFMIN(nb_samples, am->in[i].nb_samples);
234 234
     if (!nb_samples)
235
-        return;
235
+        return 0;
236 236
 
237 237
     outbuf = ff_get_audio_buffer(ctx->outputs[0], AV_PERM_WRITE, nb_samples);
238 238
     outs = outbuf->data[0];
... ...
@@ -285,7 +285,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
285 285
             }
286 286
         }
287 287
     }
288
-    ff_filter_samples(ctx->outputs[0], outbuf);
288
+    return ff_filter_samples(ctx->outputs[0], outbuf);
289 289
 }
290 290
 
291 291
 static av_cold int init(AVFilterContext *ctx, const char *args)
... ...
@@ -305,9 +305,7 @@ static int output_frame(AVFilterLink *outlink, int nb_samples)
305 305
     if (s->next_pts != AV_NOPTS_VALUE)
306 306
         s->next_pts += nb_samples;
307 307
 
308
-    ff_filter_samples(outlink, out_buf);
309
-
310
-    return 0;
308
+    return ff_filter_samples(outlink, out_buf);
311 309
 }
312 310
 
313 311
 /**
... ...
@@ -448,31 +446,37 @@ static int request_frame(AVFilterLink *outlink)
448 448
     return output_frame(outlink, available_samples);
449 449
 }
450 450
 
451
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
451
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
452 452
 {
453 453
     AVFilterContext  *ctx = inlink->dst;
454 454
     MixContext       *s = ctx->priv;
455 455
     AVFilterLink *outlink = ctx->outputs[0];
456
-    int i;
456
+    int i, ret = 0;
457 457
 
458 458
     for (i = 0; i < ctx->nb_inputs; i++)
459 459
         if (ctx->inputs[i] == inlink)
460 460
             break;
461 461
     if (i >= ctx->nb_inputs) {
462 462
         av_log(ctx, AV_LOG_ERROR, "unknown input link\n");
463
-        return;
463
+        ret = AVERROR(EINVAL);
464
+        goto fail;
464 465
     }
465 466
 
466 467
     if (i == 0) {
467 468
         int64_t pts = av_rescale_q(buf->pts, inlink->time_base,
468 469
                                    outlink->time_base);
469
-        frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
470
+        ret = frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
471
+        if (ret < 0)
472
+            goto fail;
470 473
     }
471 474
 
472
-    av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
473
-                        buf->audio->nb_samples);
475
+    ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
476
+                              buf->audio->nb_samples);
474 477
 
478
+fail:
475 479
     avfilter_unref_buffer(buf);
480
+
481
+    return ret;
476 482
 }
477 483
 
478 484
 static int init(AVFilterContext *ctx, const char *args)
... ...
@@ -168,13 +168,14 @@ static int config_output(AVFilterLink *outlink)
168 168
     return 0;
169 169
 }
170 170
 
171
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
171
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
172 172
 {
173 173
     AResampleContext *aresample = inlink->dst->priv;
174 174
     const int n_in  = insamplesref->audio->nb_samples;
175 175
     int n_out       = n_in * aresample->ratio * 2 ;
176 176
     AVFilterLink *const outlink = inlink->dst->outputs[0];
177 177
     AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
178
+    int ret;
178 179
 
179 180
 
180 181
     avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
... ...
@@ -193,15 +194,16 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref
193 193
     if (n_out <= 0) {
194 194
         avfilter_unref_buffer(outsamplesref);
195 195
         avfilter_unref_buffer(insamplesref);
196
-        return;
196
+        return 0;
197 197
     }
198 198
 
199 199
     outsamplesref->audio->sample_rate = outlink->sample_rate;
200 200
     outsamplesref->audio->nb_samples  = n_out;
201 201
 
202
-    ff_filter_samples(outlink, outsamplesref);
202
+    ret = ff_filter_samples(outlink, outsamplesref);
203 203
     aresample->req_fullfilled= 1;
204 204
     avfilter_unref_buffer(insamplesref);
205
+    return ret;
205 206
 }
206 207
 
207 208
 static int request_frame(AVFilterLink *outlink)
... ...
@@ -131,7 +131,7 @@ static int push_samples(AVFilterLink *outlink)
131 131
     return nb_out_samples;
132 132
 }
133 133
 
134
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
134
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
135 135
 {
136 136
     AVFilterContext *ctx = inlink->dst;
137 137
     ASNSContext *asns = ctx->priv;
... ...
@@ -145,7 +145,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
145 145
         if (ret < 0) {
146 146
             av_log(ctx, AV_LOG_ERROR,
147 147
                    "Stretching audio fifo failed, discarded %d samples\n", nb_samples);
148
-            return;
148
+            return -1;
149 149
         }
150 150
     }
151 151
     av_audio_fifo_write(asns->fifo, (void **)insamples->extended_data, nb_samples);
... ...
@@ -155,6 +155,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
155 155
 
156 156
     if (av_audio_fifo_size(asns->fifo) >= asns->nb_out_samples)
157 157
         push_samples(outlink);
158
+    return 0;
158 159
 }
159 160
 
160 161
 static int request_frame(AVFilterLink *outlink)
... ...
@@ -40,7 +40,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
40 40
     return 0;
41 41
 }
42 42
 
43
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
43
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
44 44
 {
45 45
     AVFilterContext *ctx = inlink->dst;
46 46
     ShowInfoContext *showinfo = ctx->priv;
... ...
@@ -83,7 +83,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
83 83
     av_log(ctx, AV_LOG_INFO, "]\n");
84 84
 
85 85
     showinfo->frame++;
86
-    ff_filter_samples(inlink->dst->outputs[0], samplesref);
86
+    return ff_filter_samples(inlink->dst->outputs[0], samplesref);
87 87
 }
88 88
 
89 89
 AVFilter avfilter_af_ashowinfo = {
... ...
@@ -107,11 +107,12 @@ static int config_output(AVFilterLink *outlink)
107 107
     return 0;
108 108
 }
109 109
 
110
-static void send_out(AVFilterContext *ctx, int out_id)
110
+static int send_out(AVFilterContext *ctx, int out_id)
111 111
 {
112 112
     AStreamSyncContext *as = ctx->priv;
113 113
     struct buf_queue *queue = &as->queue[out_id];
114 114
     AVFilterBufferRef *buf = queue->buf[queue->tail];
115
+    int ret;
115 116
 
116 117
     queue->buf[queue->tail] = NULL;
117 118
     as->var_values[VAR_B1 + out_id]++;
... ...
@@ -121,11 +122,12 @@ static void send_out(AVFilterContext *ctx, int out_id)
121 121
             av_q2d(ctx->outputs[out_id]->time_base) * buf->pts;
122 122
     as->var_values[VAR_T1 + out_id] += buf->audio->nb_samples /
123 123
                                    (double)ctx->inputs[out_id]->sample_rate;
124
-    ff_filter_samples(ctx->outputs[out_id], buf);
124
+    ret = ff_filter_samples(ctx->outputs[out_id], buf);
125 125
     queue->nb--;
126 126
     queue->tail = (queue->tail + 1) % QUEUE_SIZE;
127 127
     if (as->req[out_id])
128 128
         as->req[out_id]--;
129
+    return ret;
129 130
 }
130 131
 
131 132
 static void send_next(AVFilterContext *ctx)
... ...
@@ -165,7 +167,7 @@ static int request_frame(AVFilterLink *outlink)
165 165
     return 0;
166 166
 }
167 167
 
168
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
168
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
169 169
 {
170 170
     AVFilterContext *ctx = inlink->dst;
171 171
     AStreamSyncContext *as = ctx->priv;
... ...
@@ -175,6 +177,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
175 175
         insamples;
176 176
     as->eof &= ~(1 << id);
177 177
     send_next(ctx);
178
+    return 0;
178 179
 }
179 180
 
180 181
 AVFilter avfilter_af_astreamsync = {
... ...
@@ -37,6 +37,9 @@ typedef struct ASyncContext {
37 37
     int resample;
38 38
     float min_delta_sec;
39 39
     int max_comp;
40
+
41
+    /* set by filter_samples() to signal an output frame to request_frame() */
42
+    int got_output;
40 43
 } ASyncContext;
41 44
 
42 45
 #define OFFSET(x) offsetof(ASyncContext, x)
... ...
@@ -112,9 +115,13 @@ static int request_frame(AVFilterLink *link)
112 112
 {
113 113
     AVFilterContext *ctx = link->src;
114 114
     ASyncContext      *s = ctx->priv;
115
-    int ret = ff_request_frame(ctx->inputs[0]);
115
+    int ret = 0;
116 116
     int nb_samples;
117 117
 
118
+    s->got_output = 0;
119
+    while (ret >= 0 && !s->got_output)
120
+        ret = ff_request_frame(ctx->inputs[0]);
121
+
118 122
     /* flush the fifo */
119 123
     if (ret == AVERROR_EOF && (nb_samples = avresample_get_delay(s->avr))) {
120 124
         AVFilterBufferRef *buf = ff_get_audio_buffer(link, AV_PERM_WRITE,
... ...
@@ -124,18 +131,18 @@ static int request_frame(AVFilterLink *link)
124 124
         avresample_convert(s->avr, (void**)buf->extended_data, buf->linesize[0],
125 125
                            nb_samples, NULL, 0, 0);
126 126
         buf->pts = s->pts;
127
-        ff_filter_samples(link, buf);
128
-        return 0;
127
+        return ff_filter_samples(link, buf);
129 128
     }
130 129
 
131 130
     return ret;
132 131
 }
133 132
 
134
-static void write_to_fifo(ASyncContext *s, AVFilterBufferRef *buf)
133
+static int write_to_fifo(ASyncContext *s, AVFilterBufferRef *buf)
135 134
 {
136
-    avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
137
-                       buf->linesize[0], buf->audio->nb_samples);
135
+    int ret = avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
136
+                                 buf->linesize[0], buf->audio->nb_samples);
138 137
     avfilter_unref_buffer(buf);
138
+    return ret;
139 139
 }
140 140
 
141 141
 /* get amount of data currently buffered, in samples */
... ...
@@ -144,7 +151,7 @@ static int64_t get_delay(ASyncContext *s)
144 144
     return avresample_available(s->avr) + avresample_get_delay(s->avr);
145 145
 }
146 146
 
147
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
147
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
148 148
 {
149 149
     AVFilterContext  *ctx = inlink->dst;
150 150
     ASyncContext       *s = ctx->priv;
... ...
@@ -152,7 +159,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
152 152
     int nb_channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout);
153 153
     int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts :
154 154
                   av_rescale_q(buf->pts, inlink->time_base, outlink->time_base);
155
-    int out_size;
155
+    int out_size, ret;
156 156
     int64_t delta;
157 157
 
158 158
     /* buffer data until we get the first timestamp */
... ...
@@ -160,14 +167,12 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
160 160
         if (pts != AV_NOPTS_VALUE) {
161 161
             s->pts = pts - get_delay(s);
162 162
         }
163
-        write_to_fifo(s, buf);
164
-        return;
163
+        return write_to_fifo(s, buf);
165 164
     }
166 165
 
167 166
     /* now wait for the next timestamp */
168 167
     if (pts == AV_NOPTS_VALUE) {
169
-        write_to_fifo(s, buf);
170
-        return;
168
+        return write_to_fifo(s, buf);
171 169
     }
172 170
 
173 171
     /* when we have two timestamps, compute how many samples would we have
... ...
@@ -190,8 +195,10 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
190 190
     if (out_size > 0) {
191 191
         AVFilterBufferRef *buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
192 192
                                                          out_size);
193
-        if (!buf_out)
194
-            return;
193
+        if (!buf_out) {
194
+            ret = AVERROR(ENOMEM);
195
+            goto fail;
196
+        }
195 197
 
196 198
         avresample_read(s->avr, (void**)buf_out->extended_data, out_size);
197 199
         buf_out->pts = s->pts;
... ...
@@ -200,7 +207,10 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
200 200
             av_samples_set_silence(buf_out->extended_data, out_size - delta,
201 201
                                    delta, nb_channels, buf->format);
202 202
         }
203
-        ff_filter_samples(outlink, buf_out);
203
+        ret = ff_filter_samples(outlink, buf_out);
204
+        if (ret < 0)
205
+            goto fail;
206
+        s->got_output = 1;
204 207
     } else {
205 208
         av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping "
206 209
                "whole buffer.\n");
... ...
@@ -210,9 +220,13 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
210 210
     avresample_read(s->avr, NULL, avresample_available(s->avr));
211 211
 
212 212
     s->pts = pts - avresample_get_delay(s->avr);
213
-    avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
214
-                       buf->linesize[0], buf->audio->nb_samples);
213
+    ret = avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data,
214
+                             buf->linesize[0], buf->audio->nb_samples);
215
+
216
+fail:
215 217
     avfilter_unref_buffer(buf);
218
+
219
+    return ret;
216 220
 }
217 221
 
218 222
 AVFilter avfilter_af_asyncts = {
... ...
@@ -1040,7 +1040,7 @@ static void push_samples(ATempoContext *atempo,
1040 1040
     atempo->nsamples_out += n_out;
1041 1041
 }
1042 1042
 
1043
-static void filter_samples(AVFilterLink *inlink,
1043
+static int filter_samples(AVFilterLink *inlink,
1044 1044
                            AVFilterBufferRef *src_buffer)
1045 1045
 {
1046 1046
     AVFilterContext  *ctx = inlink->dst;
... ...
@@ -1074,6 +1074,7 @@ static void filter_samples(AVFilterLink *inlink,
1074 1074
 
1075 1075
     atempo->nsamples_in += n_in;
1076 1076
     avfilter_unref_bufferp(&src_buffer);
1077
+    return 0;
1077 1078
 }
1078 1079
 
1079 1080
 static int request_frame(AVFilterLink *outlink)
... ...
@@ -313,7 +313,7 @@ static int channelmap_query_formats(AVFilterContext *ctx)
313 313
     return 0;
314 314
 }
315 315
 
316
-static void channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
316
+static int channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
317 317
 {
318 318
     AVFilterContext  *ctx = inlink->dst;
319 319
     AVFilterLink *outlink = ctx->outputs[0];
... ...
@@ -330,8 +330,10 @@ static void channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *b
330 330
         if (nch_out > FF_ARRAY_ELEMS(buf->data)) {
331 331
             uint8_t **new_extended_data =
332 332
                 av_mallocz(nch_out * sizeof(*buf->extended_data));
333
-            if (!new_extended_data)
334
-                return;
333
+            if (!new_extended_data) {
334
+                avfilter_unref_buffer(buf);
335
+                return AVERROR(ENOMEM);
336
+            }
335 337
             if (buf->extended_data == buf->data) {
336 338
                 buf->extended_data = new_extended_data;
337 339
             } else {
... ...
@@ -353,7 +355,7 @@ static void channelmap_filter_samples(AVFilterLink *inlink, AVFilterBufferRef *b
353 353
         memcpy(buf->data, buf->extended_data,
354 354
            FFMIN(FF_ARRAY_ELEMS(buf->data), nch_out) * sizeof(buf->data[0]));
355 355
 
356
-    ff_filter_samples(outlink, buf);
356
+    return ff_filter_samples(outlink, buf);
357 357
 }
358 358
 
359 359
 static int channelmap_config_input(AVFilterLink *inlink)
... ...
@@ -105,24 +105,29 @@ static int query_formats(AVFilterContext *ctx)
105 105
     return 0;
106 106
 }
107 107
 
108
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
108
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
109 109
 {
110 110
     AVFilterContext *ctx = inlink->dst;
111
-    int i;
111
+    int i, ret = 0;
112 112
 
113 113
     for (i = 0; i < ctx->nb_outputs; i++) {
114 114
         AVFilterBufferRef *buf_out = avfilter_ref_buffer(buf, ~AV_PERM_WRITE);
115 115
 
116
-        if (!buf_out)
117
-            return;
116
+        if (!buf_out) {
117
+            ret = AVERROR(ENOMEM);
118
+            break;
119
+        }
118 120
 
119 121
         buf_out->data[0] = buf_out->extended_data[0] = buf_out->extended_data[i];
120 122
         buf_out->audio->channel_layout =
121 123
             av_channel_layout_extract_channel(buf->audio->channel_layout, i);
122 124
 
123
-        ff_filter_samples(ctx->outputs[i], buf_out);
125
+        ret = ff_filter_samples(ctx->outputs[i], buf_out);
126
+        if (ret < 0)
127
+            break;
124 128
     }
125 129
     avfilter_unref_buffer(buf);
130
+    return ret;
126 131
 }
127 132
 
128 133
 AVFilter avfilter_af_channelsplit = {
... ...
@@ -120,13 +120,15 @@ static inline int16_t *scalarproduct(const int16_t *in, const int16_t *endin, in
120 120
     return out;
121 121
 }
122 122
 
123
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
123
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
124 124
 {
125 125
     AVFilterLink *outlink = inlink->dst->outputs[0];
126 126
     int16_t *taps, *endin, *in, *out;
127 127
     AVFilterBufferRef *outsamples =
128 128
         ff_get_audio_buffer(inlink, AV_PERM_WRITE,
129 129
                                   insamples->audio->nb_samples);
130
+    int ret;
131
+
130 132
     avfilter_copy_buffer_ref_props(outsamples, insamples);
131 133
 
132 134
     taps  = ((EarwaxContext *)inlink->dst->priv)->taps;
... ...
@@ -144,8 +146,9 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
144 144
     // save part of input for next round
145 145
     memcpy(taps, endin, NUMTAPS * sizeof(*taps));
146 146
 
147
-    ff_filter_samples(outlink, outsamples);
147
+    ret = ff_filter_samples(outlink, outsamples);
148 148
     avfilter_unref_buffer(insamples);
149
+    return ret;
149 150
 }
150 151
 
151 152
 AVFilter avfilter_af_earwax = {
... ...
@@ -92,7 +92,7 @@ static const AVClass join_class = {
92 92
     .version    = LIBAVUTIL_VERSION_INT,
93 93
 };
94 94
 
95
-static void filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
95
+static int filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
96 96
 {
97 97
     AVFilterContext *ctx = link->dst;
98 98
     JoinContext       *s = ctx->priv;
... ...
@@ -104,6 +104,8 @@ static void filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
104 104
     av_assert0(i < ctx->nb_inputs);
105 105
     av_assert0(!s->input_frames[i]);
106 106
     s->input_frames[i] = buf;
107
+
108
+    return 0;
107 109
 }
108 110
 
109 111
 static int parse_maps(AVFilterContext *ctx)
... ...
@@ -468,11 +470,11 @@ static int join_request_frame(AVFilterLink *outlink)
468 468
     priv->nb_in_buffers = ctx->nb_inputs;
469 469
     buf->buf->priv      = priv;
470 470
 
471
-    ff_filter_samples(outlink, buf);
471
+    ret = ff_filter_samples(outlink, buf);
472 472
 
473 473
     memset(s->input_frames, 0, sizeof(*s->input_frames) * ctx->nb_inputs);
474 474
 
475
-    return 0;
475
+    return ret;
476 476
 
477 477
 fail:
478 478
     avfilter_unref_buffer(buf);
... ...
@@ -343,8 +343,9 @@ static int config_props(AVFilterLink *link)
343 343
     return 0;
344 344
 }
345 345
 
346
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
346
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
347 347
 {
348
+    int ret;
348 349
     int n = insamples->audio->nb_samples;
349 350
     AVFilterLink *const outlink = inlink->dst->outputs[0];
350 351
     AVFilterBufferRef *outsamples = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n);
... ...
@@ -354,8 +355,9 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
354 354
     avfilter_copy_buffer_ref_props(outsamples, insamples);
355 355
     outsamples->audio->channel_layout = outlink->channel_layout;
356 356
 
357
-    ff_filter_samples(outlink, outsamples);
357
+    ret = ff_filter_samples(outlink, outsamples);
358 358
     avfilter_unref_buffer(insamples);
359
+    return ret;
359 360
 }
360 361
 
361 362
 static av_cold void uninit(AVFilterContext *ctx)
... ...
@@ -38,6 +38,9 @@ typedef struct ResampleContext {
38 38
     AVAudioResampleContext *avr;
39 39
 
40 40
     int64_t next_pts;
41
+
42
+    /* set by filter_samples() to signal an output frame to request_frame() */
43
+    int got_output;
41 44
 } ResampleContext;
42 45
 
43 46
 static av_cold void uninit(AVFilterContext *ctx)
... ...
@@ -102,12 +105,6 @@ static int config_output(AVFilterLink *outlink)
102 102
     av_opt_set_int(s->avr,  "in_sample_rate",    inlink ->sample_rate,    0);
103 103
     av_opt_set_int(s->avr, "out_sample_rate",    outlink->sample_rate,    0);
104 104
 
105
-    /* if both the input and output formats are s16 or u8, use s16 as
106
-       the internal sample format */
107
-    if (av_get_bytes_per_sample(inlink->format)  <= 2 &&
108
-        av_get_bytes_per_sample(outlink->format) <= 2)
109
-        av_opt_set_int(s->avr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
110
-
111 105
     if ((ret = avresample_open(s->avr)) < 0)
112 106
         return ret;
113 107
 
... ...
@@ -130,7 +127,11 @@ static int request_frame(AVFilterLink *outlink)
130 130
 {
131 131
     AVFilterContext *ctx = outlink->src;
132 132
     ResampleContext   *s = ctx->priv;
133
-    int ret = ff_request_frame(ctx->inputs[0]);
133
+    int ret = 0;
134
+
135
+    s->got_output = 0;
136
+    while (ret >= 0 && !s->got_output)
137
+        ret = ff_request_frame(ctx->inputs[0]);
134 138
 
135 139
     /* flush the lavr delay buffer */
136 140
     if (ret == AVERROR_EOF && s->avr) {
... ...
@@ -156,21 +157,21 @@ static int request_frame(AVFilterLink *outlink)
156 156
         }
157 157
 
158 158
         buf->pts = s->next_pts;
159
-        ff_filter_samples(outlink, buf);
160
-        return 0;
159
+        return ff_filter_samples(outlink, buf);
161 160
     }
162 161
     return ret;
163 162
 }
164 163
 
165
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
164
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
166 165
 {
167 166
     AVFilterContext  *ctx = inlink->dst;
168 167
     ResampleContext    *s = ctx->priv;
169 168
     AVFilterLink *outlink = ctx->outputs[0];
169
+    int ret;
170 170
 
171 171
     if (s->avr) {
172 172
         AVFilterBufferRef *buf_out;
173
-        int delay, nb_samples, ret;
173
+        int delay, nb_samples;
174 174
 
175 175
         /* maximum possible samples lavr can output */
176 176
         delay      = avresample_get_delay(s->avr);
... ...
@@ -179,10 +180,19 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
179 179
                                     AV_ROUND_UP);
180 180
 
181 181
         buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
182
+        if (!buf_out) {
183
+            ret = AVERROR(ENOMEM);
184
+            goto fail;
185
+        }
186
+
182 187
         ret     = avresample_convert(s->avr, (void**)buf_out->extended_data,
183 188
                                      buf_out->linesize[0], nb_samples,
184 189
                                      (void**)buf->extended_data, buf->linesize[0],
185 190
                                      buf->audio->nb_samples);
191
+        if (ret < 0) {
192
+            avfilter_unref_buffer(buf_out);
193
+            goto fail;
194
+        }
186 195
 
187 196
         av_assert0(!avresample_available(s->avr));
188 197
 
... ...
@@ -208,11 +218,18 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
208 208
 
209 209
             s->next_pts = buf_out->pts + buf_out->audio->nb_samples;
210 210
 
211
-            ff_filter_samples(outlink, buf_out);
211
+            ret = ff_filter_samples(outlink, buf_out);
212
+            s->got_output = 1;
212 213
         }
214
+
215
+fail:
213 216
         avfilter_unref_buffer(buf);
214
-    } else
215
-        ff_filter_samples(outlink, buf);
217
+    } else {
218
+        ret = ff_filter_samples(outlink, buf);
219
+        s->got_output = 1;
220
+    }
221
+
222
+    return ret;
216 223
 }
217 224
 
218 225
 AVFilter avfilter_af_resample = {
... ...
@@ -78,7 +78,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
78 78
     return 0;
79 79
 }
80 80
 
81
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
81
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
82 82
 {
83 83
     int i;
84 84
     SilenceDetectContext *silence = inlink->dst->priv;
... ...
@@ -118,7 +118,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
118 118
         }
119 119
     }
120 120
 
121
-    ff_filter_samples(inlink->dst->outputs[0], insamples);
121
+    return ff_filter_samples(inlink->dst->outputs[0], insamples);
122 122
 }
123 123
 
124 124
 static int query_formats(AVFilterContext *ctx)
... ...
@@ -110,7 +110,7 @@ static int query_formats(AVFilterContext *ctx)
110 110
     return 0;
111 111
 }
112 112
 
113
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
113
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
114 114
 {
115 115
     VolumeContext *vol = inlink->dst->priv;
116 116
     AVFilterLink *outlink = inlink->dst->outputs[0];
... ...
@@ -169,7 +169,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
169 169
         }
170 170
         }
171 171
     }
172
-    ff_filter_samples(outlink, insamples);
172
+    return ff_filter_samples(outlink, insamples);
173 173
 }
174 174
 
175 175
 AVFilter avfilter_af_volume = {
... ...
@@ -21,7 +21,10 @@
21 21
 #include "avfilter.h"
22 22
 #include "internal.h"
23 23
 
24
-static void null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) { }
24
+static int null_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
25
+{
26
+    return 0;
27
+}
25 28
 
26 29
 AVFilter avfilter_asink_anullsink = {
27 30
     .name        = "anullsink",
... ...
@@ -150,19 +150,19 @@ fail:
150 150
     return NULL;
151 151
 }
152 152
 
153
-static void default_filter_samples(AVFilterLink *link,
154
-                                   AVFilterBufferRef *samplesref)
153
+static int default_filter_samples(AVFilterLink *link,
154
+                                  AVFilterBufferRef *samplesref)
155 155
 {
156
-    ff_filter_samples(link->dst->outputs[0], samplesref);
156
+    return ff_filter_samples(link->dst->outputs[0], samplesref);
157 157
 }
158 158
 
159
-void ff_filter_samples_framed(AVFilterLink *link,
160
-                              AVFilterBufferRef *samplesref)
159
+int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
161 160
 {
162
-    void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
161
+    int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
163 162
     AVFilterPad *dst = link->dstpad;
164 163
     int64_t pts;
165 164
     AVFilterBufferRef *buf_out;
165
+    int ret;
166 166
 
167 167
     FF_TPRINTF_START(NULL, filter_samples); ff_tlog_link(NULL, link, 1);
168 168
 
... ...
@@ -193,21 +193,22 @@ void ff_filter_samples_framed(AVFilterLink *link,
193 193
 
194 194
     link->cur_buf = buf_out;
195 195
     pts = buf_out->pts;
196
-    filter_samples(link, buf_out);
196
+    ret = filter_samples(link, buf_out);
197 197
     ff_update_link_current_pts(link, pts);
198
+    return ret;
198 199
 }
199 200
 
200
-void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
201
+int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
201 202
 {
202 203
     int insamples = samplesref->audio->nb_samples, inpos = 0, nb_samples;
203 204
     AVFilterBufferRef *pbuf = link->partial_buf;
204 205
     int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
206
+    int ret = 0;
205 207
 
206 208
     if (!link->min_samples ||
207 209
         (!pbuf &&
208 210
          insamples >= link->min_samples && insamples <= link->max_samples)) {
209
-        ff_filter_samples_framed(link, samplesref);
210
-        return;
211
+        return ff_filter_samples_framed(link, samplesref);
211 212
     }
212 213
     /* Handle framing (min_samples, max_samples) */
213 214
     while (insamples) {
... ...
@@ -218,7 +219,7 @@ void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
218 218
             if (!pbuf) {
219 219
                 av_log(link->dst, AV_LOG_WARNING,
220 220
                        "Samples dropped due to memory allocation failure.\n");
221
-                return;
221
+                return 0;
222 222
             }
223 223
             avfilter_copy_buffer_ref_props(pbuf, samplesref);
224 224
             pbuf->pts = samplesref->pts +
... ...
@@ -234,10 +235,11 @@ void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
234 234
         insamples               -= nb_samples;
235 235
         pbuf->audio->nb_samples += nb_samples;
236 236
         if (pbuf->audio->nb_samples >= link->min_samples) {
237
-            ff_filter_samples_framed(link, pbuf);
237
+            ret = ff_filter_samples_framed(link, pbuf);
238 238
             pbuf = NULL;
239 239
         }
240 240
     }
241 241
     avfilter_unref_buffer(samplesref);
242 242
     link->partial_buf = pbuf;
243
+    return ret;
243 244
 }
... ...
@@ -70,14 +70,17 @@ AVFilterBufferRef *ff_get_audio_buffer(AVFilterLink *link, int perms,
70 70
  * @param samplesref a reference to the buffer of audio samples being sent. The
71 71
  *                   receiving filter will free this reference when it no longer
72 72
  *                   needs it or pass it on to the next filter.
73
+ *
74
+ * @return >= 0 on success, a negative AVERROR on error. The receiving filter
75
+ * is responsible for unreferencing samplesref in case of error.
73 76
  */
74
-void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
77
+int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
75 78
 
76 79
 /**
77 80
  * Send a buffer of audio samples to the next link, without checking
78 81
  * min_samples.
79 82
  */
80
-void ff_filter_samples_framed(AVFilterLink *link,
83
+int ff_filter_samples_framed(AVFilterLink *link,
81 84
                               AVFilterBufferRef *samplesref);
82 85
 
83 86
 #endif /* AVFILTER_AUDIO_H */
... ...
@@ -180,7 +180,7 @@ static int request_frame(AVFilterLink *outlink)
180 180
 
181 181
 #define MAX_INT16 ((1<<15) -1)
182 182
 
183
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
183
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
184 184
 {
185 185
     AVFilterContext *ctx = inlink->dst;
186 186
     AVFilterLink *outlink = ctx->outputs[0];
... ...
@@ -225,6 +225,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
225 225
     }
226 226
 
227 227
     avfilter_unref_buffer(insamples);
228
+    return 0;
228 229
 }
229 230
 
230 231
 AVFilter avfilter_avf_showwaves = {
... ...
@@ -301,8 +301,12 @@ struct AVFilterPad {
301 301
      * and should do its processing.
302 302
      *
303 303
      * Input audio pads only.
304
+     *
305
+     * @return >= 0 on success, a negative AVERROR on error. This function
306
+     * must ensure that samplesref is properly unreferenced on error if it
307
+     * hasn't been passed on to another filter.
304 308
      */
305
-    void (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
309
+    int (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
306 310
 
307 311
     /**
308 312
      * Frame poll callback. This returns the number of immediately available
... ...
@@ -56,6 +56,12 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *buf)
56 56
     link->cur_buf = NULL;
57 57
 };
58 58
 
59
+static int filter_samples(AVFilterLink *link, AVFilterBufferRef *buf)
60
+{
61
+    start_frame(link, buf);
62
+    return 0;
63
+}
64
+
59 65
 int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
60 66
 {
61 67
     BufferSinkContext *s    = ctx->priv;
... ...
@@ -160,7 +166,7 @@ AVFilter avfilter_asink_abuffer = {
160 160
 
161 161
     .inputs    = (AVFilterPad[]) {{ .name           = "default",
162 162
                                     .type           = AVMEDIA_TYPE_AUDIO,
163
-                                    .filter_samples = start_frame,
163
+                                    .filter_samples = filter_samples,
164 164
                                     .min_perms      = AV_PERM_READ,
165 165
                                     .needs_fifo     = 1 },
166 166
                                   { .name = NULL }},
... ...
@@ -408,6 +408,7 @@ static int request_frame(AVFilterLink *link)
408 408
 {
409 409
     BufferSourceContext *c = link->src->priv;
410 410
     AVFilterBufferRef *buf;
411
+    int ret = 0;
411 412
 
412 413
     if (!av_fifo_size(c->fifo)) {
413 414
         if (c->eof)
... ...
@@ -424,7 +425,7 @@ static int request_frame(AVFilterLink *link)
424 424
         ff_end_frame(link);
425 425
         break;
426 426
     case AVMEDIA_TYPE_AUDIO:
427
-        ff_filter_samples(link, avfilter_ref_buffer(buf, ~0));
427
+        ret = ff_filter_samples(link, avfilter_ref_buffer(buf, ~0));
428 428
         break;
429 429
     default:
430 430
         return AVERROR(EINVAL);
... ...
@@ -432,7 +433,7 @@ static int request_frame(AVFilterLink *link)
432 432
 
433 433
     avfilter_unref_buffer(buf);
434 434
 
435
-    return 0;
435
+    return ret;
436 436
 }
437 437
 
438 438
 static int poll_frame(AVFilterLink *link)
... ...
@@ -117,7 +117,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
117 117
     ff_start_frame(outlink, picref2);
118 118
 }
119 119
 
120
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
120
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
121 121
 {
122 122
     AVFilterContext *ctx = inlink->dst;
123 123
     AVFilterLink *outlink = ctx->outputs[0];
... ...
@@ -132,7 +132,7 @@ static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
132 132
         avfilter_unref_buffer(insamples);
133 133
     }
134 134
 
135
-    ff_filter_samples(outlink, outsamples);
135
+    return ff_filter_samples(outlink, outsamples);
136 136
 }
137 137
 
138 138
 #if CONFIG_SETTB_FILTER
... ...
@@ -72,13 +72,25 @@ static av_cold void uninit(AVFilterContext *ctx)
72 72
     avfilter_unref_buffer(fifo->buf_out);
73 73
 }
74 74
 
75
-static void add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
75
+static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf)
76 76
 {
77 77
     FifoContext *fifo = inlink->dst->priv;
78 78
 
79 79
     fifo->last->next = av_mallocz(sizeof(Buf));
80
+    if (!fifo->last->next) {
81
+        avfilter_unref_buffer(buf);
82
+        return AVERROR(ENOMEM);
83
+    }
84
+
80 85
     fifo->last = fifo->last->next;
81 86
     fifo->last->buf = buf;
87
+
88
+    return 0;
89
+}
90
+
91
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
92
+{
93
+    add_to_queue(inlink, buf);
82 94
 }
83 95
 
84 96
 static void queue_pop(FifoContext *s)
... ...
@@ -210,15 +222,13 @@ static int return_audio_frame(AVFilterContext *ctx)
210 210
         buf_out = s->buf_out;
211 211
         s->buf_out = NULL;
212 212
     }
213
-    ff_filter_samples(link, buf_out);
214
-
215
-    return 0;
213
+    return ff_filter_samples(link, buf_out);
216 214
 }
217 215
 
218 216
 static int request_frame(AVFilterLink *outlink)
219 217
 {
220 218
     FifoContext *fifo = outlink->src->priv;
221
-    int ret;
219
+    int ret = 0;
222 220
 
223 221
     if (!fifo->root.next) {
224 222
         if ((ret = ff_request_frame(outlink->src->inputs[0])) < 0)
... ...
@@ -238,7 +248,7 @@ static int request_frame(AVFilterLink *outlink)
238 238
         if (outlink->request_samples) {
239 239
             return return_audio_frame(outlink->src);
240 240
         } else {
241
-            ff_filter_samples(outlink, fifo->root.next->buf);
241
+            ret = ff_filter_samples(outlink, fifo->root.next->buf);
242 242
             queue_pop(fifo);
243 243
         }
244 244
         break;
... ...
@@ -246,7 +256,7 @@ static int request_frame(AVFilterLink *outlink)
246 246
         return AVERROR(EINVAL);
247 247
     }
248 248
 
249
-    return 0;
249
+    return ret;
250 250
 }
251 251
 
252 252
 AVFilter avfilter_vf_fifo = {
... ...
@@ -261,7 +271,7 @@ AVFilter avfilter_vf_fifo = {
261 261
     .inputs    = (const AVFilterPad[]) {{ .name      = "default",
262 262
                                     .type            = AVMEDIA_TYPE_VIDEO,
263 263
                                     .get_video_buffer= ff_null_get_video_buffer,
264
-                                    .start_frame     = add_to_queue,
264
+                                    .start_frame     = start_frame,
265 265
                                     .draw_slice      = draw_slice,
266 266
                                     .end_frame       = end_frame,
267 267
                                     .rej_perms       = AV_PERM_REUSE2, },
... ...
@@ -135,8 +135,12 @@ struct AVFilterPad {
135 135
      * and should do its processing.
136 136
      *
137 137
      * Input audio pads only.
138
+     *
139
+     * @return >= 0 on success, a negative AVERROR on error. This function
140
+     * must ensure that samplesref is properly unreferenced on error if it
141
+     * hasn't been passed on to another filter.
138 142
      */
139
-    void (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
143
+    int (*filter_samples)(AVFilterLink *link, AVFilterBufferRef *samplesref);
140 144
 
141 145
     /**
142 146
      * Frame poll callback. This returns the number of immediately available
... ...
@@ -244,9 +244,10 @@ AVFilter avfilter_vsink_buffersink = {
244 244
 
245 245
 #if CONFIG_ABUFFERSINK_FILTER
246 246
 
247
-static void filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
247
+static int filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
248 248
 {
249 249
     end_frame(link);
250
+    return 0;
250 251
 }
251 252
 
252 253
 static av_cold int asink_init(AVFilterContext *ctx, const char *args)
... ...
@@ -110,15 +110,19 @@ AVFilter avfilter_vf_split = {
110 110
     .outputs   = (AVFilterPad[]) {{ .name = NULL}},
111 111
 };
112 112
 
113
-static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
113
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
114 114
 {
115 115
     AVFilterContext *ctx = inlink->dst;
116
-    int i;
116
+    int i, ret = 0;
117 117
 
118
-    for (i = 0; i < ctx->nb_outputs; i++)
119
-        ff_filter_samples(inlink->dst->outputs[i],
120
-                          avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE));
118
+    for (i = 0; i < ctx->nb_outputs; i++) {
119
+        ret = ff_filter_samples(inlink->dst->outputs[i],
120
+                                avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE));
121
+        if (ret < 0)
122
+            break;
123
+    }
121 124
     avfilter_unref_buffer(samplesref);
125
+    return ret;
122 126
 }
123 127
 
124 128
 AVFilter avfilter_af_asplit = {
... ...
@@ -842,8 +842,11 @@ static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax,
842 842
         matroska->num_levels > 0 &&
843 843
         matroska->levels[matroska->num_levels-1].length == 0xffffffffffffff)
844 844
         return 0;  // we reached the end of an unknown size cluster
845
-    if (!syntax[i].id && id != EBML_ID_VOID && id != EBML_ID_CRC32)
845
+    if (!syntax[i].id && id != EBML_ID_VOID && id != EBML_ID_CRC32) {
846 846
         av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id);
847
+        if (matroska->ctx->error_recognition & AV_EF_EXPLODE)
848
+            return AVERROR_INVALIDDATA;
849
+    }
847 850
     return ebml_parse_elem(matroska, &syntax[i], data);
848 851
 }
849 852
 
... ...
@@ -43,7 +43,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
43 43
     char buf[256];
44 44
     int ret;
45 45
     socklen_t optlen;
46
-    int timeout = 50;
46
+    int timeout = 50, listen_timeout = -1;
47 47
     char hostname[1024],proto[1024],path[1024];
48 48
     char portstr[10];
49 49
 
... ...
@@ -59,6 +59,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
59 59
         if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
60 60
             timeout = strtol(buf, NULL, 10);
61 61
         }
62
+        if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
63
+            listen_timeout = strtol(buf, NULL, 10);
64
+        }
62 65
     }
63 66
     hints.ai_family = AF_UNSPEC;
64 67
     hints.ai_socktype = SOCK_STREAM;
... ...
@@ -87,6 +90,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
87 87
     if (listen_socket) {
88 88
         int fd1;
89 89
         int reuse = 1;
90
+        struct pollfd lp = { fd, POLLIN, 0 };
90 91
         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
91 92
         ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
92 93
         if (ret) {
... ...
@@ -98,6 +102,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
98 98
             ret = ff_neterrno();
99 99
             goto fail1;
100 100
         }
101
+        ret = poll(&lp, 1, listen_timeout >= 0 ? listen_timeout : -1);
102
+        if (ret <= 0) {
103
+            ret = AVERROR(ETIMEDOUT);
104
+            goto fail1;
105
+        }
101 106
         fd1 = accept(fd, NULL, NULL);
102 107
         if (fd1 < 0) {
103 108
             ret = ff_neterrno();
... ...
@@ -305,6 +305,14 @@ int ff_audio_mix_init(AVAudioResampleContext *avr)
305 305
 {
306 306
     int ret;
307 307
 
308
+    if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P &&
309
+        avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP) {
310
+        av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
311
+               "mixing: %s\n",
312
+               av_get_sample_fmt_name(avr->internal_sample_fmt));
313
+        return AVERROR(EINVAL);
314
+    }
315
+
308 316
     /* build matrix if the user did not already set one */
309 317
     if (!avr->am->matrix) {
310 318
         int i, j;
... ...
@@ -45,6 +45,13 @@ enum AVMixCoeffType {
45 45
     AV_MIX_COEFF_TYPE_NB,   /** Number of coeff types. Not part of ABI      */
46 46
 };
47 47
 
48
+/** Resampling Filter Types */
49
+enum AVResampleFilterType {
50
+    AV_RESAMPLE_FILTER_TYPE_CUBIC,              /**< Cubic */
51
+    AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL,   /**< Blackman Nuttall Windowed Sinc */
52
+    AV_RESAMPLE_FILTER_TYPE_KAISER,             /**< Kaiser Windowed Sinc */
53
+};
54
+
48 55
 /**
49 56
  * Return the LIBAVRESAMPLE_VERSION_INT constant.
50 57
  */
... ...
@@ -50,6 +50,8 @@ struct AVAudioResampleContext {
50 50
     int phase_shift;                            /**< log2 of the number of entries in the resampling polyphase filterbank */
51 51
     int linear_interp;                          /**< if 1 then the resampling FIR filter will be linearly interpolated */
52 52
     double cutoff;                              /**< resampling cutoff frequency. 1.0 corresponds to half the output sample rate */
53
+    enum AVResampleFilterType filter_type;      /**< resampling filter type */
54
+    int kaiser_beta;                            /**< beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) */
53 55
 
54 56
     int in_channels;        /**< number of input channels                   */
55 57
     int out_channels;       /**< number of output channels                  */
... ...
@@ -39,7 +39,7 @@ static const AVOption options[] = {
39 39
     { "out_channel_layout",     "Output Channel Layout",    OFFSET(out_channel_layout),     AV_OPT_TYPE_INT64,  { 0                     }, INT64_MIN,            INT64_MAX,              PARAM },
40 40
     { "out_sample_fmt",         "Output Sample Format",     OFFSET(out_sample_fmt),         AV_OPT_TYPE_INT,    { AV_SAMPLE_FMT_S16     }, AV_SAMPLE_FMT_U8,     AV_SAMPLE_FMT_NB-1,     PARAM },
41 41
     { "out_sample_rate",        "Output Sample Rate",       OFFSET(out_sample_rate),        AV_OPT_TYPE_INT,    { 48000                 }, 1,                    INT_MAX,                PARAM },
42
-    { "internal_sample_fmt",    "Internal Sample Format",   OFFSET(internal_sample_fmt),    AV_OPT_TYPE_INT,    { AV_SAMPLE_FMT_FLTP    }, AV_SAMPLE_FMT_NONE,   AV_SAMPLE_FMT_NB-1,     PARAM },
42
+    { "internal_sample_fmt",    "Internal Sample Format",   OFFSET(internal_sample_fmt),    AV_OPT_TYPE_INT,    { AV_SAMPLE_FMT_NONE    }, AV_SAMPLE_FMT_NONE,   AV_SAMPLE_FMT_NB-1,     PARAM },
43 43
     { "mix_coeff_type",         "Mixing Coefficient Type",  OFFSET(mix_coeff_type),         AV_OPT_TYPE_INT,    { AV_MIX_COEFF_TYPE_FLT }, AV_MIX_COEFF_TYPE_Q8, AV_MIX_COEFF_TYPE_NB-1, PARAM, "mix_coeff_type" },
44 44
         { "q8",  "16-bit 8.8 Fixed-Point",   0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_Q8  }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
45 45
         { "q15", "32-bit 17.15 Fixed-Point", 0, AV_OPT_TYPE_CONST, { AV_MIX_COEFF_TYPE_Q15 }, INT_MIN, INT_MAX, PARAM, "mix_coeff_type" },
... ...
@@ -56,6 +56,11 @@ static const AVOption options[] = {
56 56
         { "none",  "None",               0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_NONE  }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
57 57
         { "dolby", "Dolby",              0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DOLBY }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
58 58
         { "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
59
+    { "filter_type",            "Filter Type",              OFFSET(filter_type),            AV_OPT_TYPE_INT,    { AV_RESAMPLE_FILTER_TYPE_KAISER }, AV_RESAMPLE_FILTER_TYPE_CUBIC, AV_RESAMPLE_FILTER_TYPE_KAISER,  PARAM, "filter_type" },
60
+        { "cubic",            "Cubic",                          0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_CUBIC            }, INT_MIN, INT_MAX, PARAM, "filter_type" },
61
+        { "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
62
+        { "kaiser",           "Kaiser Windowed Sinc",           0, AV_OPT_TYPE_CONST, { AV_RESAMPLE_FILTER_TYPE_KAISER           }, INT_MIN, INT_MAX, PARAM, "filter_type" },
63
+    { "kaiser_beta",            "Kaiser Window Beta",       OFFSET(kaiser_beta),            AV_OPT_TYPE_INT,    { 9                     }, 2,                    16,                     PARAM },
59 64
     { NULL },
60 65
 };
61 66
 
... ...
@@ -24,37 +24,10 @@
24 24
 #include "internal.h"
25 25
 #include "audio_data.h"
26 26
 
27
-#ifdef CONFIG_RESAMPLE_FLT
28
-/* float template */
29
-#define FILTER_SHIFT  0
30
-#define FELEM         float
31
-#define FELEM2        float
32
-#define FELEML        float
33
-#define WINDOW_TYPE   24
34
-#elifdef CONFIG_RESAMPLE_S32
35
-/* s32 template */
36
-#define FILTER_SHIFT  30
37
-#define FELEM         int32_t
38
-#define FELEM2        int64_t
39
-#define FELEML        int64_t
40
-#define FELEM_MAX     INT32_MAX
41
-#define FELEM_MIN     INT32_MIN
42
-#define WINDOW_TYPE   12
43
-#else
44
-/* s16 template */
45
-#define FILTER_SHIFT  15
46
-#define FELEM         int16_t
47
-#define FELEM2        int32_t
48
-#define FELEML        int64_t
49
-#define FELEM_MAX     INT16_MAX
50
-#define FELEM_MIN     INT16_MIN
51
-#define WINDOW_TYPE   9
52
-#endif
53
-
54 27
 struct ResampleContext {
55 28
     AVAudioResampleContext *avr;
56 29
     AudioData *buffer;
57
-    FELEM *filter_bank;
30
+    uint8_t *filter_bank;
58 31
     int filter_length;
59 32
     int ideal_dst_incr;
60 33
     int dst_incr;
... ...
@@ -65,9 +38,35 @@ struct ResampleContext {
65 65
     int phase_shift;
66 66
     int phase_mask;
67 67
     int linear;
68
+    enum AVResampleFilterType filter_type;
69
+    int kaiser_beta;
68 70
     double factor;
71
+    void (*set_filter)(void *filter, double *tab, int phase, int tap_count);
72
+    void (*resample_one)(struct ResampleContext *c, int no_filter, void *dst0,
73
+                         int dst_index, const void *src0, int src_size,
74
+                         int index, int frac);
69 75
 };
70 76
 
77
+
78
+/* double template */
79
+#define CONFIG_RESAMPLE_DBL
80
+#include "resample_template.c"
81
+#undef CONFIG_RESAMPLE_DBL
82
+
83
+/* float template */
84
+#define CONFIG_RESAMPLE_FLT
85
+#include "resample_template.c"
86
+#undef CONFIG_RESAMPLE_FLT
87
+
88
+/* s32 template */
89
+#define CONFIG_RESAMPLE_S32
90
+#include "resample_template.c"
91
+#undef CONFIG_RESAMPLE_S32
92
+
93
+/* s16 template */
94
+#include "resample_template.c"
95
+
96
+
71 97
 /**
72 98
  * 0th order modified bessel function of the first kind.
73 99
  */
... ...
@@ -95,17 +94,17 @@ static double bessel(double x)
95 95
  * @param      tap_count    tap count
96 96
  * @param      phase_count  phase count
97 97
  * @param      scale        wanted sum of coefficients for each filter
98
- * @param      type         0->cubic
99
- *                          1->blackman nuttall windowed sinc
100
- *                          2..16->kaiser windowed sinc beta=2..16
98
+ * @param      filter_type  filter type
99
+ * @param      kaiser_beta  kaiser window beta
101 100
  * @return                  0 on success, negative AVERROR code on failure
102 101
  */
103
-static int build_filter(FELEM *filter, double factor, int tap_count,
104
-                        int phase_count, int scale, int type)
102
+static int build_filter(ResampleContext *c)
105 103
 {
106 104
     int ph, i;
107
-    double x, y, w;
105
+    double x, y, w, factor;
108 106
     double *tab;
107
+    int tap_count    = c->filter_length;
108
+    int phase_count  = 1 << c->phase_shift;
109 109
     const int center = (tap_count - 1) / 2;
110 110
 
111 111
     tab = av_malloc(tap_count * sizeof(*tab));
... ...
@@ -113,8 +112,7 @@ static int build_filter(FELEM *filter, double factor, int tap_count,
113 113
         return AVERROR(ENOMEM);
114 114
 
115 115
     /* if upsampling, only need to interpolate, no filter */
116
-    if (factor > 1.0)
117
-        factor = 1.0;
116
+    factor = FFMIN(c->factor, 1.0);
118 117
 
119 118
     for (ph = 0; ph < phase_count; ph++) {
120 119
         double norm = 0;
... ...
@@ -122,39 +120,34 @@ static int build_filter(FELEM *filter, double factor, int tap_count,
122 122
             x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
123 123
             if (x == 0) y = 1.0;
124 124
             else        y = sin(x) / x;
125
-            switch (type) {
126
-            case 0: {
125
+            switch (c->filter_type) {
126
+            case AV_RESAMPLE_FILTER_TYPE_CUBIC: {
127 127
                 const float d = -0.5; //first order derivative = -0.5
128 128
                 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
129 129
                 if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * (                -x*x + x*x*x);
130 130
                 else         y =                           d * (-4 + 8 * x - 5 * x*x + x*x*x);
131 131
                 break;
132 132
             }
133
-            case 1:
133
+            case AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL:
134 134
                 w  = 2.0 * x / (factor * tap_count) + M_PI;
135 135
                 y *= 0.3635819 - 0.4891775 * cos(    w) +
136 136
                                  0.1365995 * cos(2 * w) -
137 137
                                  0.0106411 * cos(3 * w);
138 138
                 break;
139
-            default:
139
+            case AV_RESAMPLE_FILTER_TYPE_KAISER:
140 140
                 w  = 2.0 * x / (factor * tap_count * M_PI);
141
-                y *= bessel(type * sqrt(FFMAX(1 - w * w, 0)));
141
+                y *= bessel(c->kaiser_beta * sqrt(FFMAX(1 - w * w, 0)));
142 142
                 break;
143 143
             }
144 144
 
145 145
             tab[i] = y;
146 146
             norm  += y;
147 147
         }
148
-
149 148
         /* normalize so that an uniform color remains the same */
150
-        for (i = 0; i < tap_count; i++) {
151
-#ifdef CONFIG_RESAMPLE_FLT
152
-            filter[ph * tap_count + i] = tab[i] / norm;
153
-#else
154
-            filter[ph * tap_count + i] = av_clip(lrintf(tab[i] * scale / norm),
155
-                                                 FELEM_MIN, FELEM_MAX);
156
-#endif
157
-        }
149
+        for (i = 0; i < tap_count; i++)
150
+            tab[i] = tab[i] / norm;
151
+
152
+        c->set_filter(c->filter_bank, tab, ph, tap_count);
158 153
     }
159 154
 
160 155
     av_free(tab);
... ...
@@ -168,9 +161,12 @@ ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr)
168 168
     int in_rate     = avr->in_sample_rate;
169 169
     double factor   = FFMIN(out_rate * avr->cutoff / in_rate, 1.0);
170 170
     int phase_count = 1 << avr->phase_shift;
171
+    int felem_size;
171 172
 
172
-    /* TODO: add support for s32 and float internal formats */
173
-    if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P) {
173
+    if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P &&
174
+        avr->internal_sample_fmt != AV_SAMPLE_FMT_S32P &&
175
+        avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP &&
176
+        avr->internal_sample_fmt != AV_SAMPLE_FMT_DBLP) {
174 177
         av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
175 178
                "resampling: %s\n",
176 179
                av_get_sample_fmt_name(avr->internal_sample_fmt));
... ...
@@ -186,18 +182,40 @@ ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr)
186 186
     c->linear        = avr->linear_interp;
187 187
     c->factor        = factor;
188 188
     c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
189
+    c->filter_type   = avr->filter_type;
190
+    c->kaiser_beta   = avr->kaiser_beta;
191
+
192
+    switch (avr->internal_sample_fmt) {
193
+    case AV_SAMPLE_FMT_DBLP:
194
+        c->resample_one  = resample_one_dbl;
195
+        c->set_filter    = set_filter_dbl;
196
+        break;
197
+    case AV_SAMPLE_FMT_FLTP:
198
+        c->resample_one  = resample_one_flt;
199
+        c->set_filter    = set_filter_flt;
200
+        break;
201
+    case AV_SAMPLE_FMT_S32P:
202
+        c->resample_one  = resample_one_s32;
203
+        c->set_filter    = set_filter_s32;
204
+        break;
205
+    case AV_SAMPLE_FMT_S16P:
206
+        c->resample_one  = resample_one_s16;
207
+        c->set_filter    = set_filter_s16;
208
+        break;
209
+    }
189 210
 
190
-    c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * sizeof(FELEM));
211
+    felem_size = av_get_bytes_per_sample(avr->internal_sample_fmt);
212
+    c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * felem_size);
191 213
     if (!c->filter_bank)
192 214
         goto error;
193 215
 
194
-    if (build_filter(c->filter_bank, factor, c->filter_length, phase_count,
195
-                     1 << FILTER_SHIFT, WINDOW_TYPE) < 0)
216
+    if (build_filter(c) < 0)
196 217
         goto error;
197 218
 
198
-    memcpy(&c->filter_bank[c->filter_length * phase_count + 1],
199
-           c->filter_bank, (c->filter_length - 1) * sizeof(FELEM));
200
-    c->filter_bank[c->filter_length * phase_count] = c->filter_bank[c->filter_length - 1];
219
+    memcpy(&c->filter_bank[(c->filter_length * phase_count + 1) * felem_size],
220
+           c->filter_bank, (c->filter_length - 1) * felem_size);
221
+    memcpy(&c->filter_bank[c->filter_length * phase_count * felem_size],
222
+           &c->filter_bank[(c->filter_length - 1) * felem_size], felem_size);
201 223
 
202 224
     c->compensation_distance = 0;
203 225
     if (!av_reduce(&c->src_incr, &c->dst_incr, out_rate,
... ...
@@ -311,10 +329,10 @@ reinit_fail:
311 311
     return ret;
312 312
 }
313 313
 
314
-static int resample(ResampleContext *c, int16_t *dst, const int16_t *src,
314
+static int resample(ResampleContext *c, void *dst, const void *src,
315 315
                     int *consumed, int src_size, int dst_size, int update_ctx)
316 316
 {
317
-    int dst_index, i;
317
+    int dst_index;
318 318
     int index         = c->index;
319 319
     int frac          = c->frac;
320 320
     int dst_incr_frac = c->dst_incr % c->src_incr;
... ...
@@ -334,7 +352,7 @@ static int resample(ResampleContext *c, int16_t *dst, const int16_t *src,
334 334
 
335 335
         if (dst) {
336 336
             for(dst_index = 0; dst_index < dst_size; dst_index++) {
337
-                dst[dst_index] = src[index2 >> 32];
337
+                c->resample_one(c, 1, dst, dst_index, src, 0, index2 >> 32, 0);
338 338
                 index2 += incr;
339 339
             }
340 340
         } else {
... ...
@@ -345,42 +363,14 @@ static int resample(ResampleContext *c, int16_t *dst, const int16_t *src,
345 345
         frac   = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
346 346
     } else {
347 347
         for (dst_index = 0; dst_index < dst_size; dst_index++) {
348
-            FELEM *filter = c->filter_bank +
349
-                            c->filter_length * (index & c->phase_mask);
350 348
             int sample_index = index >> c->phase_shift;
351 349
 
352
-            if (!dst && (sample_index + c->filter_length > src_size ||
353
-                         -sample_index >= src_size))
350
+            if (sample_index + c->filter_length > src_size ||
351
+                -sample_index >= src_size)
354 352
                 break;
355 353
 
356
-            if (dst) {
357
-                FELEM2 val = 0;
358
-
359
-                if (sample_index < 0) {
360
-                    for (i = 0; i < c->filter_length; i++)
361
-                        val += src[FFABS(sample_index + i) % src_size] *
362
-                               (FELEM2)filter[i];
363
-                } else if (sample_index + c->filter_length > src_size) {
364
-                    break;
365
-                } else if (c->linear) {
366
-                    FELEM2 v2 = 0;
367
-                    for (i = 0; i < c->filter_length; i++) {
368
-                        val += src[abs(sample_index + i)] * (FELEM2)filter[i];
369
-                        v2  += src[abs(sample_index + i)] * (FELEM2)filter[i + c->filter_length];
370
-                    }
371
-                    val += (v2 - val) * (FELEML)frac / c->src_incr;
372
-                } else {
373
-                    for (i = 0; i < c->filter_length; i++)
374
-                        val += src[sample_index + i] * (FELEM2)filter[i];
375
-                }
376
-
377
-#ifdef CONFIG_RESAMPLE_FLT
378
-                dst[dst_index] = av_clip_int16(lrintf(val));
379
-#else
380
-                val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;
381
-                dst[dst_index] = av_clip_int16(val);
382
-#endif
383
-            }
354
+            if (dst)
355
+                c->resample_one(c, 0, dst, dst_index, src, src_size, index, frac);
384 356
 
385 357
             frac  += dst_incr_frac;
386 358
             index += dst_incr;
... ...
@@ -451,8 +441,8 @@ int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src,
451 451
 
452 452
     /* resample each channel plane */
453 453
     for (ch = 0; ch < c->buffer->channels; ch++) {
454
-        out_samples = resample(c, (int16_t *)dst->data[ch],
455
-                               (const int16_t *)c->buffer->data[ch], consumed,
454
+        out_samples = resample(c, (void *)dst->data[ch],
455
+                               (const void *)c->buffer->data[ch], consumed,
456 456
                                c->buffer->nb_samples, dst->allocated_samples,
457 457
                                ch + 1 == c->buffer->channels);
458 458
     }
459 459
new file mode 100644
... ...
@@ -0,0 +1,102 @@
0
+/*
1
+ * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
2
+ *
3
+ * This file is part of FFmpeg.
4
+ *
5
+ * FFmpeg is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * FFmpeg is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with FFmpeg; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+#if defined(CONFIG_RESAMPLE_DBL)
21
+#define SET_TYPE(func)  func ## _dbl
22
+#define FELEM         double
23
+#define FELEM2        double
24
+#define FELEML        double
25
+#define OUT(d, v) d = v
26
+#define DBL_TO_FELEM(d, v) d = v
27
+#elif defined(CONFIG_RESAMPLE_FLT)
28
+#define SET_TYPE(func)  func ## _flt
29
+#define FELEM         float
30
+#define FELEM2        float
31
+#define FELEML        float
32
+#define OUT(d, v) d = v
33
+#define DBL_TO_FELEM(d, v) d = v
34
+#elif defined(CONFIG_RESAMPLE_S32)
35
+#define SET_TYPE(func)  func ## _s32
36
+#define FELEM         int32_t
37
+#define FELEM2        int64_t
38
+#define FELEML        int64_t
39
+#define OUT(d, v) d = av_clipl_int32((v + (1 << 29)) >> 30)
40
+#define DBL_TO_FELEM(d, v) d = av_clipl_int32(llrint(v * (1 << 30)));
41
+#else
42
+#define SET_TYPE(func)  func ## _s16
43
+#define FELEM         int16_t
44
+#define FELEM2        int32_t
45
+#define FELEML        int64_t
46
+#define OUT(d, v) d = av_clip_int16((v + (1 << 14)) >> 15)
47
+#define DBL_TO_FELEM(d, v) d = av_clip_int16(lrint(v * (1 << 15)))
48
+#endif
49
+
50
+static void SET_TYPE(resample_one)(ResampleContext *c, int no_filter,
51
+                                   void *dst0, int dst_index, const void *src0,
52
+                                   int src_size, int index, int frac)
53
+{
54
+    FELEM *dst = dst0;
55
+    const FELEM *src = src0;
56
+
57
+    if (no_filter) {
58
+        dst[dst_index] = src[index];
59
+    } else {
60
+        int i;
61
+        int sample_index = index >> c->phase_shift;
62
+        FELEM2 val = 0;
63
+        FELEM *filter = ((FELEM *)c->filter_bank) +
64
+                        c->filter_length * (index & c->phase_mask);
65
+
66
+        if (sample_index < 0) {
67
+            for (i = 0; i < c->filter_length; i++)
68
+                val += src[FFABS(sample_index + i) % src_size] *
69
+                       (FELEM2)filter[i];
70
+        } else if (c->linear) {
71
+            FELEM2 v2 = 0;
72
+            for (i = 0; i < c->filter_length; i++) {
73
+                val += src[abs(sample_index + i)] * (FELEM2)filter[i];
74
+                v2  += src[abs(sample_index + i)] * (FELEM2)filter[i + c->filter_length];
75
+            }
76
+            val += (v2 - val) * (FELEML)frac / c->src_incr;
77
+        } else {
78
+            for (i = 0; i < c->filter_length; i++)
79
+                val += src[sample_index + i] * (FELEM2)filter[i];
80
+        }
81
+
82
+        OUT(dst[dst_index], val);
83
+    }
84
+}
85
+
86
+static void SET_TYPE(set_filter)(void *filter0, double *tab, int phase,
87
+                                 int tap_count)
88
+{
89
+    int i;
90
+    FELEM *filter = ((FELEM *)filter0) + phase * tap_count;
91
+    for (i = 0; i < tap_count; i++) {
92
+        DBL_TO_FELEM(filter[i], tab[i]);
93
+    }
94
+}
95
+
96
+#undef SET_TYPE
97
+#undef FELEM
98
+#undef FELEM2
99
+#undef FELEML
100
+#undef OUT
101
+#undef DBL_TO_FELEM
... ...
@@ -57,18 +57,43 @@ int avresample_open(AVAudioResampleContext *avr)
57 57
     avr->resample_needed   = avr->in_sample_rate != avr->out_sample_rate ||
58 58
                              avr->force_resampling;
59 59
 
60
-    /* set sample format conversion parameters */
61
-    /* override user-requested internal format to avoid unexpected failures
62
-       TODO: support more internal formats */
63
-    if (avr->resample_needed && avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P) {
64
-        av_log(avr, AV_LOG_WARNING, "Using s16p as internal sample format\n");
65
-        avr->internal_sample_fmt = AV_SAMPLE_FMT_S16P;
66
-    } else if (avr->mixing_needed &&
67
-               avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P &&
68
-               avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP) {
69
-        av_log(avr, AV_LOG_WARNING, "Using fltp as internal sample format\n");
70
-        avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;
60
+    /* select internal sample format if not specified by the user */
61
+    if (avr->internal_sample_fmt == AV_SAMPLE_FMT_NONE &&
62
+        (avr->mixing_needed || avr->resample_needed)) {
63
+        enum AVSampleFormat  in_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);
64
+        enum AVSampleFormat out_fmt = av_get_planar_sample_fmt(avr->out_sample_fmt);
65
+        int max_bps = FFMAX(av_get_bytes_per_sample(in_fmt),
66
+                            av_get_bytes_per_sample(out_fmt));
67
+        if (max_bps <= 2) {
68
+            avr->internal_sample_fmt = AV_SAMPLE_FMT_S16P;
69
+        } else if (avr->mixing_needed) {
70
+            avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;
71
+        } else {
72
+            if (max_bps <= 4) {
73
+                if (in_fmt  == AV_SAMPLE_FMT_S32P ||
74
+                    out_fmt == AV_SAMPLE_FMT_S32P) {
75
+                    if (in_fmt  == AV_SAMPLE_FMT_FLTP ||
76
+                        out_fmt == AV_SAMPLE_FMT_FLTP) {
77
+                        /* if one is s32 and the other is flt, use dbl */
78
+                        avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP;
79
+                    } else {
80
+                        /* if one is s32 and the other is s32, s16, or u8, use s32 */
81
+                        avr->internal_sample_fmt = AV_SAMPLE_FMT_S32P;
82
+                    }
83
+                } else {
84
+                    /* if one is flt and the other is flt, s16 or u8, use flt */
85
+                    avr->internal_sample_fmt = AV_SAMPLE_FMT_FLTP;
86
+                }
87
+            } else {
88
+                /* if either is dbl, use dbl */
89
+                avr->internal_sample_fmt = AV_SAMPLE_FMT_DBLP;
90
+            }
91
+        }
92
+        av_log(avr, AV_LOG_DEBUG, "Using %s as internal sample format\n",
93
+               av_get_sample_fmt_name(avr->internal_sample_fmt));
71 94
     }
95
+
96
+    /* set sample format conversion parameters */
72 97
     if (avr->in_channels == 1)
73 98
         avr->in_sample_fmt = av_get_planar_sample_fmt(avr->in_sample_fmt);
74 99
     if (avr->out_channels == 1)
... ...
@@ -75,7 +75,13 @@ probefmt(){
75 75
 }
76 76
 
77 77
 ffmpeg(){
78
-    run ffmpeg -nostats -threads $threads -thread_type $thread_type -cpuflags $cpuflags "$@"
78
+    dec_opts="-threads $threads -thread_type $thread_type"
79
+    ffmpeg_args="-nostats -cpuflags $cpuflags"
80
+    for arg in $@; do
81
+        [ ${arg} = -i ] && ffmpeg_args="${ffmpeg_args} ${dec_opts}"
82
+        ffmpeg_args="${ffmpeg_args} ${arg}"
83
+    done
84
+    run ffmpeg ${ffmpeg_args}
79 85
 }
80 86
 
81 87
 framecrc(){