FFmpeg
swresample_resample_realloc.c
Go to the documentation of this file.
1 /*
2  * Exercise the swr_convert(N) -> swr_convert(2N) edge case where the
3  * second call reuses the internal preout buffer at full capacity, with
4  * no trailing slack from swri_realloc_audio()'s amortized doubling.
5  * Forces internal_sample_fmt=S16P to reach the int16 SIMD resample path.
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include <stdint.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 
29 #include "libavutil/mem.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/samplefmt.h"
33 
34 int main(void)
35 {
36  const int IN_RATE = 48000;
37  const int OUT_RATE = 16000;
38  /* First call asks for N out frames, second call asks for 2N. */
39  const int N1_OUT = 160;
40  const int N2_OUT = 320;
41  const int N1_IN = N1_OUT * IN_RATE / OUT_RATE; /* 480 */
42  const int N2_IN = N2_OUT * IN_RATE / OUT_RATE; /* 960 */
43 
44  SwrContext *swr = swr_alloc();
46  int ret = 0;
47 
48  if (!swr) {
49  fprintf(stderr, "swr_alloc failed\n");
50  return 1;
51  }
52 
53  av_opt_set_chlayout (swr, "in_chlayout", &mono, 0);
54  av_opt_set_chlayout (swr, "out_chlayout", &mono, 0);
55  av_opt_set_int (swr, "in_sample_rate", IN_RATE, 0);
56  av_opt_set_int (swr, "out_sample_rate", OUT_RATE, 0);
57  av_opt_set_sample_fmt (swr, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
58  av_opt_set_sample_fmt (swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
59  /* Force the int16 SIMD resample path. */
60  av_opt_set_sample_fmt (swr, "internal_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
61 
62  if ((ret = swr_init(swr)) < 0) {
63  fprintf(stderr, "swr_init failed: %d\n", ret);
64  ret = 1;
65  goto end;
66  }
67 
68  {
69  int16_t *input = av_calloc(N2_IN, sizeof(int16_t));
70  int16_t *out = av_calloc(N2_OUT, sizeof(int16_t));
71  const uint8_t *in_planes[1];
72  uint8_t *out_planes[1];
73  int i, n;
74 
75  if (!input || !out) {
76  fprintf(stderr, "alloc failed\n");
77  av_free(input);
78  av_free(out);
79  ret = 1;
80  goto end;
81  }
82 
83  /* Non-zero samples so the SIMD inner loop produces real data. */
84  for (i = 0; i < N2_IN; ++i)
85  input[i] = (int16_t)((i * 7) & 0x3fff);
86 
87  /* Call #1: out_count = N. swri_realloc_audio() doubles count and
88  * grows s->preout to capacity 2N (e.g. 640 bytes for N=160). */
89  in_planes[0] = (const uint8_t *)input;
90  out_planes[0] = (uint8_t *)out;
91  n = swr_convert(swr, out_planes, N1_OUT, in_planes, N1_IN);
92  if (n < 0) {
93  fprintf(stderr, "swr_convert call#1 failed: %d\n", n);
94  av_free(input);
95  av_free(out);
96  ret = 1;
97  goto end;
98  }
99 
100  /* Call #2: out_count = 2N. a->count == 2N, so swri_realloc_audio()
101  * skips realloc and reuses the existing buffer at full capacity. */
102  in_planes[0] = (const uint8_t *)input;
103  out_planes[0] = (uint8_t *)out;
104  n = swr_convert(swr, out_planes, N2_OUT, in_planes, N2_IN);
105  if (n < 0) {
106  fprintf(stderr, "swr_convert call#2 failed: %d\n", n);
107  av_free(input);
108  av_free(out);
109  ret = 1;
110  goto end;
111  }
112 
113  av_free(input);
114  av_free(out);
115  }
116 
117 end:
118  swr_free(&swr);
119  return ret;
120 }
opt.h
out
static FILE * out
Definition: movenc.c:55
samplefmt.h
main
int main(void)
Definition: swresample_resample_realloc.c:34
swr_convert
int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *const *out_arg, int out_count, const uint8_t *const *in_arg, int in_count)
Convert audio.
Definition: swresample.c:725
swr_init
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:156
swr_alloc
av_cold struct SwrContext * swr_alloc(void)
Allocate SwrContext.
Definition: options.c:148
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
swresample.h
av_opt_set_int
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:869
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
av_opt_set_chlayout
int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *channel_layout, int search_flags)
Definition: opt.c:989
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
swr_free
av_cold void swr_free(SwrContext **ss)
Free the given SwrContext and set the pointer to NULL.
Definition: swresample.c:137
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:64
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:58
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
ret
ret
Definition: filter_design.txt:187
channel_layout.h
mem.h
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_opt_set_sample_fmt
int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags)
Definition: opt.c:968