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"
23 #include "libavutil/frame.h"
24 #include "libavutil/opt.h"
25 
27 {
28  swr_close(s);
29 
30  if (in) {
31  if (av_opt_set_int(s, "icl", in->channel_layout, 0) < 0)
32  goto fail;
33  if (av_opt_set_int(s, "isf", in->format, 0) < 0)
34  goto fail;
35  if (av_opt_set_int(s, "isr", in->sample_rate, 0) < 0)
36  goto fail;
37  }
38 
39  if (out) {
40  if (av_opt_set_int(s, "ocl", out->channel_layout, 0) < 0)
41  goto fail;
42  if (av_opt_set_int(s, "osf", out->format, 0) < 0)
43  goto fail;
44  if (av_opt_set_int(s, "osr", out->sample_rate, 0) < 0)
45  goto fail;
46  }
47 
48  return 0;
49 fail:
50  av_log(s, AV_LOG_ERROR, "Failed to set option\n");
51  return AVERROR(EINVAL);
52 }
53 
55  const AVFrame *out, const AVFrame *in)
56 {
57  int ret = 0;
58 
59  if (in) {
60  if (s->in_ch_layout != in->channel_layout ||
61  s->in_sample_rate != in->sample_rate ||
62  s->in_sample_fmt != in->format) {
64  }
65  }
66 
67  if (out) {
68  if (s->out_ch_layout != out->channel_layout ||
69  s->out_sample_rate != out->sample_rate ||
70  s->out_sample_fmt != out->format) {
72  }
73  }
74 
75  return ret;
76 }
77 
78 static inline int convert_frame(SwrContext *s,
79  AVFrame *out, const AVFrame *in)
80 {
81  int ret;
82  uint8_t **out_data = NULL;
83  const uint8_t **in_data = NULL;
84  int out_nb_samples = 0, in_nb_samples = 0;
85 
86  if (out) {
87  out_data = out->extended_data;
88  out_nb_samples = out->nb_samples;
89  }
90 
91  if (in) {
92  in_data = (const uint8_t **)in->extended_data;
93  in_nb_samples = in->nb_samples;
94  }
95 
96  ret = swr_convert(s, out_data, out_nb_samples, in_data, in_nb_samples);
97 
98  if (ret < 0) {
99  if (out)
100  out->nb_samples = 0;
101  return ret;
102  }
103 
104  if (out)
105  out->nb_samples = ret;
106 
107  return 0;
108 }
109 
110 static inline int available_samples(AVFrame *out)
111 {
112  int bytes_per_sample = av_get_bytes_per_sample(out->format);
113  int samples = out->linesize[0] / bytes_per_sample;
114 
115  if (av_sample_fmt_is_planar(out->format)) {
116  return samples;
117  } else {
118  int channels = av_get_channel_layout_nb_channels(out->channel_layout);
119  return samples / channels;
120  }
121 }
122 
124  AVFrame *out, const AVFrame *in)
125 {
126  int ret, setup = 0;
127 
128  if (!swr_is_initialized(s)) {
129  if ((ret = swr_config_frame(s, out, in)) < 0)
130  return ret;
131  if ((ret = swr_init(s)) < 0)
132  return ret;
133  setup = 1;
134  } else {
135  // return as is or reconfigure for input changes?
136  if ((ret = config_changed(s, out, in)))
137  return ret;
138  }
139 
140  if (out) {
141  if (!out->linesize[0]) {
142  out->nb_samples = swr_get_delay(s, s->out_sample_rate) + 3;
143  if (in) {
144  out->nb_samples += in->nb_samples*(int64_t)s->out_sample_rate / s->in_sample_rate;
145  }
146  if ((ret = av_frame_get_buffer(out, 0)) < 0) {
147  if (setup)
148  swr_close(s);
149  return ret;
150  }
151  } else {
152  if (!out->nb_samples)
153  out->nb_samples = available_samples(out);
154  }
155  }
156 
157  return convert_frame(s, out, in);
158 }
159 
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
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:325
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
convert_frame
static int convert_frame(SwrContext *s, AVFrame *out, const AVFrame *in)
Definition: swresample_frame.c:78
fail
#define fail()
Definition: checkasm.h:123
swr_is_initialized
int swr_is_initialized(struct SwrContext *s)
Check whether an swr context has been initialized or not.
Definition: swresample.c:710
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:867
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
swr_init
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:152
available_samples
static int available_samples(AVFrame *out)
Definition: swresample_frame.c:110
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:73
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:112
swr_convert
int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count, const uint8_t *in_arg[SWR_CH_MAX], int in_count)
Definition: swresample.c:714
channels
channels
Definition: aptx.h:33
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
NULL
#define NULL
Definition: coverity.c:32
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:220
av_opt_set_int
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:586
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:123
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:74
frame.h
swresample_internal.h
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
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:26
uint8_t
uint8_t
Definition: audio_convert.c:194
config_changed
static int config_changed(SwrContext *s, const AVFrame *out, const AVFrame *in)
Definition: swresample_frame.c:54
ret
ret
Definition: filter_design.txt:187
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
swr_close
av_cold void swr_close(SwrContext *s)
Closes the context so that swr_is_initialized() returns 0.
Definition: swresample.c:148
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28