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 FF_API_OLD_CHANNEL_LAYOUT
37  // if the old/new fields are set inconsistently, prefer the old ones
38  if ((in->channel_layout && (in->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
39  in->ch_layout.u.mask != in->channel_layout))) {
40  av_channel_layout_from_mask(&ch_layout, in->channel_layout);
42  } else
43 #endif
44  if ((ret = av_channel_layout_copy(&ch_layout, &in->ch_layout)) < 0)
45  goto fail;
46  if ((ret = av_opt_set_chlayout(s, "ichl", &ch_layout, 0)) < 0)
47  goto fail;
48  if ((ret = av_opt_set_int(s, "isf", in->format, 0)) < 0)
49  goto fail;
50  if ((ret = av_opt_set_int(s, "isr", in->sample_rate, 0)) < 0)
51  goto fail;
52  }
53 
54  if (out) {
55 #if FF_API_OLD_CHANNEL_LAYOUT
57  // if the old/new fields are set inconsistently, prefer the old ones
58  if ((out->channel_layout && (out->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
59  out->ch_layout.u.mask != out->channel_layout))) {
60  av_channel_layout_uninit(&ch_layout);
61  av_channel_layout_from_mask(&ch_layout, out->channel_layout);
63  } else
64 #endif
65  if ((ret = av_channel_layout_copy(&ch_layout, &out->ch_layout)) < 0)
66  goto fail;
67  if ((ret = av_opt_set_chlayout(s, "ochl", &ch_layout, 0)) < 0)
68  goto fail;
69  if ((ret = av_opt_set_int(s, "osf", out->format, 0)) < 0)
70  goto fail;
71  if ((ret = av_opt_set_int(s, "osr", out->sample_rate, 0)) < 0)
72  goto fail;
73  }
74 
75  ret = 0;
76 fail:
77  if (ret < 0)
78  av_log(s, AV_LOG_ERROR, "Failed to set option\n");
79  av_channel_layout_uninit(&ch_layout);
80  return ret;
81 }
82 
84  const AVFrame *out, const AVFrame *in)
85 {
86  AVChannelLayout ch_layout = { 0 };
87  int ret = 0;
88 
89  if (in) {
90 #if FF_API_OLD_CHANNEL_LAYOUT
92  // if the old/new fields are set inconsistently, prefer the old ones
93  if ((in->channel_layout && (in->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
94  in->ch_layout.u.mask != in->channel_layout))) {
95  av_channel_layout_from_mask(&ch_layout, in->channel_layout);
97  } else
98 #endif
99  if ((ret = av_channel_layout_copy(&ch_layout, &in->ch_layout)) < 0)
100  return ret;
101  if (av_channel_layout_compare(&s->in_ch_layout, &ch_layout) ||
102  s->in_sample_rate != in->sample_rate ||
103  s->in_sample_fmt != in->format) {
105  }
106  }
107 
108  if (out) {
109 #if FF_API_OLD_CHANNEL_LAYOUT
111  // if the old/new fields are set inconsistently, prefer the old ones
112  if ((out->channel_layout && (out->ch_layout.order != AV_CHANNEL_ORDER_NATIVE ||
113  out->ch_layout.u.mask != out->channel_layout))) {
114  av_channel_layout_uninit(&ch_layout);
115  av_channel_layout_from_mask(&ch_layout, out->channel_layout);
117  } else
118 #endif
119  if ((ret = av_channel_layout_copy(&ch_layout, &out->ch_layout)) < 0)
120  return ret;
121  if (av_channel_layout_compare(&s->out_ch_layout, &ch_layout) ||
122  s->out_sample_rate != out->sample_rate ||
123  s->out_sample_fmt != out->format) {
125  }
126  }
127  av_channel_layout_uninit(&ch_layout);
128 
129  return ret;
130 }
131 
132 static inline int convert_frame(SwrContext *s,
133  AVFrame *out, const AVFrame *in)
134 {
135  int ret;
136  uint8_t **out_data = NULL;
137  const uint8_t **in_data = NULL;
138  int out_nb_samples = 0, in_nb_samples = 0;
139 
140  if (out) {
141  out_data = out->extended_data;
142  out_nb_samples = out->nb_samples;
143  }
144 
145  if (in) {
146  in_data = (const uint8_t **)in->extended_data;
147  in_nb_samples = in->nb_samples;
148  }
149 
150  ret = swr_convert(s, out_data, out_nb_samples, in_data, in_nb_samples);
151 
152  if (ret < 0) {
153  if (out)
154  out->nb_samples = 0;
155  return ret;
156  }
157 
158  if (out)
159  out->nb_samples = ret;
160 
161  return 0;
162 }
163 
164 static inline int available_samples(AVFrame *out)
165 {
166  int bytes_per_sample = av_get_bytes_per_sample(out->format);
167  int samples = out->linesize[0] / bytes_per_sample;
168 
169  if (av_sample_fmt_is_planar(out->format)) {
170  return samples;
171  } else {
172  int channels;
173 #if FF_API_OLD_CHANNEL_LAYOUT
177  if (!channels)
178 #endif
179  channels = out->ch_layout.nb_channels;
180  return samples / channels;
181  }
182 }
183 
185  AVFrame *out, const AVFrame *in)
186 {
187  int ret, setup = 0;
188 
189  if (!swr_is_initialized(s)) {
190  if ((ret = swr_config_frame(s, out, in)) < 0)
191  return ret;
192  if ((ret = swr_init(s)) < 0)
193  return ret;
194  setup = 1;
195  } else {
196  // return as is or reconfigure for input changes?
197  if ((ret = config_changed(s, out, in)))
198  return ret;
199  }
200 
201  if (out) {
202  if (!out->linesize[0]) {
203  out->nb_samples = swr_get_delay(s, s->out_sample_rate) + 3;
204  if (in) {
205  out->nb_samples += in->nb_samples*(int64_t)s->out_sample_rate / s->in_sample_rate;
206  }
207  if ((ret = av_frame_get_buffer(out, 0)) < 0) {
208  if (setup)
209  swr_close(s);
210  return ret;
211  }
212  } else {
213  if (!out->nb_samples)
214  out->nb_samples = available_samples(out);
215  }
216  }
217 
218  return convert_frame(s, out, in);
219 }
220 
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:83
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:254
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
convert_frame
static int convert_frame(SwrContext *s, AVFrame *out, const AVFrame *in)
Definition: swresample_frame.c:132
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:637
fail
#define fail()
Definition: checkasm.h:131
swr_is_initialized
int swr_is_initialized(struct SwrContext *s)
Check whether an swr context has been initialized or not.
Definition: swresample.c:796
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:955
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AV_CHANNEL_ORDER_NATIVE
@ AV_CHANNEL_ORDER_NATIVE
The native channel order, i.e.
Definition: channel_layout.h:112
swr_init
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:191
available_samples
static int available_samples(AVFrame *out)
Definition: swresample_frame.c:164
s
#define s(width, name)
Definition: cbs_vp9.c:256
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:32
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
NULL
#define NULL
Definition: coverity.c:32
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:930
av_opt_set_int
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:624
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:630
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:184
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:290
av_opt_set_chlayout
int av_opt_set_chlayout(void *obj, const char *name, const AVChannelLayout *channel_layout, int search_flags)
Definition: opt.c:786
av_get_channel_layout_nb_channels
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
Definition: channel_layout.c:318
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
swr_convert
int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t **out_arg, int out_count, const uint8_t **in_arg, int in_count)
Convert audio.
Definition: swresample.c:800
frame.h
swresample_internal.h
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:83
av_channel_layout_from_mask
FF_ENABLE_DEPRECATION_WARNINGS int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:389
ret
ret
Definition: filter_design.txt:187
channel_layout.h
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:82
SwrContext::in
AudioData in
input audio data
Definition: swresample_internal.h:152
swr_close
av_cold void swr_close(SwrContext *s)
Closes the context so that swr_is_initialized() returns 0.
Definition: swresample.c:187
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27