FFmpeg
swresample_frame.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Luca Barbato <lu_zero@gentoo.org>
3  * Copyright (c) 2014 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "swresample_internal.h"
24 #include "libavutil/frame.h"
25 #include "libavutil/opt.h"
26 
28 {
29  AVChannelLayout ch_layout = { 0 };
30  int ret;
31 
32  swr_close(s);
33 
34  if (in) {
35  if ((ret = av_channel_layout_copy(&ch_layout, &in->ch_layout)) < 0)
36  goto fail;
37  if ((ret = av_opt_set_chlayout(s, "ichl", &ch_layout, 0)) < 0)
38  goto fail;
39  if ((ret = av_opt_set_int(s, "isf", in->format, 0)) < 0)
40  goto fail;
41  if ((ret = av_opt_set_int(s, "isr", in->sample_rate, 0)) < 0)
42  goto fail;
43  }
44 
45  if (out) {
46  if ((ret = av_channel_layout_copy(&ch_layout, &out->ch_layout)) < 0)
47  goto fail;
48  if ((ret = av_opt_set_chlayout(s, "ochl", &ch_layout, 0)) < 0)
49  goto fail;
50  if ((ret = av_opt_set_int(s, "osf", out->format, 0)) < 0)
51  goto fail;
52  if ((ret = av_opt_set_int(s, "osr", out->sample_rate, 0)) < 0)
53  goto fail;
54  }
55 
56  ret = 0;
57 fail:
58  if (ret < 0)
59  av_log(s, AV_LOG_ERROR, "Failed to set option\n");
60  av_channel_layout_uninit(&ch_layout);
61  return ret;
62 }
63 
65  const AVFrame *out, const AVFrame *in)
66 {
67  AVChannelLayout ch_layout = { 0 };
68  int ret = 0, err;
69 
70  if (in) {
71  if ((err = av_channel_layout_copy(&ch_layout, &in->ch_layout)) < 0)
72  return err;
73  if (av_channel_layout_compare(&s->in_ch_layout, &ch_layout) ||
74  s->in_sample_rate != in->sample_rate ||
75  s->in_sample_fmt != in->format) {
77  }
78  }
79 
80  if (out) {
81  if ((err = av_channel_layout_copy(&ch_layout, &out->ch_layout)) < 0)
82  return err;
83  if (av_channel_layout_compare(&s->out_ch_layout, &ch_layout) ||
84  s->out_sample_rate != out->sample_rate ||
85  s->out_sample_fmt != out->format) {
87  }
88  }
89  av_channel_layout_uninit(&ch_layout);
90 
91  return ret;
92 }
93 
94 static inline int convert_frame(SwrContext *s,
95  AVFrame *out, const AVFrame *in)
96 {
97  int ret;
98  uint8_t **out_data = NULL;
99  const uint8_t **in_data = NULL;
100  int out_nb_samples = 0, in_nb_samples = 0;
101 
102  if (out) {
103  out_data = out->extended_data;
104  out_nb_samples = out->nb_samples;
105  }
106 
107  if (in) {
108  in_data = (const uint8_t **)in->extended_data;
109  in_nb_samples = in->nb_samples;
110  }
111 
112  ret = swr_convert(s, out_data, out_nb_samples, in_data, in_nb_samples);
113 
114  if (ret < 0) {
115  if (out)
116  out->nb_samples = 0;
117  return ret;
118  }
119 
120  if (out)
121  out->nb_samples = ret;
122 
123  return 0;
124 }
125 
126 static inline int available_samples(AVFrame *out)
127 {
128  int bytes_per_sample = av_get_bytes_per_sample(out->format);
129  int samples = out->linesize[0] / bytes_per_sample;
130 
131  if (av_sample_fmt_is_planar(out->format)) {
132  return samples;
133  } else {
134  int channels = out->ch_layout.nb_channels;
135  return samples / channels;
136  }
137 }
138 
140  AVFrame *out, const AVFrame *in)
141 {
142  int ret, setup = 0;
143 
144  if (!swr_is_initialized(s)) {
145  if ((ret = swr_config_frame(s, out, in)) < 0)
146  return ret;
147  if ((ret = swr_init(s)) < 0)
148  return ret;
149  setup = 1;
150  } else {
151  // return as is or reconfigure for input changes?
152  if ((ret = config_changed(s, out, in)))
153  return ret;
154  }
155 
156  if (out) {
157  if (!out->linesize[0]) {
158  out->nb_samples = swr_get_delay(s, s->out_sample_rate) + 3;
159  if (in) {
160  out->nb_samples += in->nb_samples*(int64_t)s->out_sample_rate / s->in_sample_rate;
161  }
162  if ((ret = av_frame_get_buffer(out, 0)) < 0) {
163  if (setup)
164  swr_close(s);
165  return ret;
166  }
167  } else {
168  if (!out->nb_samples)
169  out->nb_samples = available_samples(out);
170  }
171  }
172 
173  return convert_frame(s, out, in);
174 }
175 
opt.h
out
FILE * out
Definition: movenc.c:54
av_frame_get_buffer
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition: frame.c:258
int64_t
long long int64_t
Definition: coverity.c:34
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:344
convert_frame
static int convert_frame(SwrContext *s, AVFrame *out, const AVFrame *in)
Definition: swresample_frame.c:94
fail
#define fail()
Definition: checkasm.h:179
swr_is_initialized
int swr_is_initialized(struct SwrContext *s)
Check whether an swr context has been initialized or not.
Definition: swresample.c:714
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:718
swr_get_delay
int64_t swr_get_delay(struct SwrContext *s, int64_t base)
Gets the delay the next input sample will experience relative to the next output sample.
Definition: swresample.c:873
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
swr_init
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:139
available_samples
static int available_samples(AVFrame *out)
Definition: swresample_frame.c:126
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVERROR_INPUT_CHANGED
#define AVERROR_INPUT_CHANGED
Input changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_OUTPUT_CHANGED)
Definition: error.h:75
av_sample_fmt_is_planar
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:114
channels
channels
Definition: aptx.h:31
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
NULL
#define NULL
Definition: coverity.c:32
av_opt_set_int
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:789
swr_convert_frame
int swr_convert_frame(SwrContext *s, AVFrame *out, const AVFrame *in)
Convert the samples in the input AVFrame and write them to the output AVFrame.
Definition: swresample_frame.c:139
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:303
av_opt_set_chlayout
int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *channel_layout, int search_flags)
Definition: opt.c:932
AVERROR_OUTPUT_CHANGED
#define AVERROR_OUTPUT_CHANGED
Output changed between calls. Reconfiguration is required. (can be OR-ed with AVERROR_INPUT_CHANGED)
Definition: error.h:76
frame.h
swresample_internal.h
av_channel_layout_compare
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
Definition: channel_layout.c:800
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:108
swr_config_frame
int swr_config_frame(SwrContext *s, const AVFrame *out, const AVFrame *in)
Configure or reconfigure the SwrContext using the information provided by the AVFrames.
Definition: swresample_frame.c:27
config_changed
static int config_changed(SwrContext *s, const AVFrame *out, const AVFrame *in)
Definition: swresample_frame.c:64
ret
ret
Definition: filter_design.txt:187
channel_layout.h
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:432
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
av_channel_layout_copy
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
Definition: channel_layout.c:439
SwrContext::in
AudioData in
input audio data
Definition: swresample_internal.h:146
swr_close
av_cold void swr_close(SwrContext *s)
Closes the context so that swr_is_initialized() returns 0.
Definition: swresample.c:135
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27