FFmpeg  4.3
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
samples
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new samples
Definition: fate.txt:139
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
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