FFmpeg
dither.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2013 Michael Niedermayer (michaelni@gmx.at)
3  *
4  * This file is part of libswresample
5  *
6  * libswresample is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * libswresample is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with libswresample; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
22 #include "swresample_internal.h"
23 
24 #include "noise_shaping_data.c"
25 
26 int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt) {
27  double scale = s->dither.noise_scale;
28 #define TMP_EXTRA 2
29  double *tmp = av_malloc_array(len + TMP_EXTRA, sizeof(double));
30  int i;
31 
32  if (!tmp)
33  return AVERROR(ENOMEM);
34 
35  for(i=0; i<len + TMP_EXTRA; i++){
36  double v;
37  seed = seed* 1664525 + 1013904223;
38 
39  switch(s->dither.method){
40  case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break;
41  default:
43  v = ((double)seed) / UINT_MAX;
44  seed = seed*1664525 + 1013904223;
45  v-= ((double)seed) / UINT_MAX;
46  break;
47  }
48  tmp[i] = v;
49  }
50 
51  for(i=0; i<len; i++){
52  double v;
53 
54  switch(s->dither.method){
55  default:
57  v = tmp[i];
58  break;
60  v = (- tmp[i] + 2*tmp[i+1] - tmp[i+2]) / sqrt(6);
61  break;
62  }
63 
64  v*= scale;
65 
66  switch(noise_fmt){
67  case AV_SAMPLE_FMT_S16P: ((int16_t*)dst)[i] = v; break;
68  case AV_SAMPLE_FMT_S32P: ((int32_t*)dst)[i] = v; break;
69  case AV_SAMPLE_FMT_FLTP: ((float *)dst)[i] = v; break;
70  case AV_SAMPLE_FMT_DBLP: ((double *)dst)[i] = v; break;
71  default: av_assert0(0);
72  }
73  }
74 
75  av_free(tmp);
76  return 0;
77 }
78 
80 {
81  int i;
82  double scale = 0;
83 
85  return AVERROR(EINVAL);
86 
87  out_fmt = av_get_packed_sample_fmt(out_fmt);
88  in_fmt = av_get_packed_sample_fmt( in_fmt);
89 
90  if(in_fmt == AV_SAMPLE_FMT_FLT || in_fmt == AV_SAMPLE_FMT_DBL){
91  if(out_fmt == AV_SAMPLE_FMT_S32) scale = 1.0/(1LL<<31);
92  if(out_fmt == AV_SAMPLE_FMT_S16) scale = 1.0/(1LL<<15);
93  if(out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1.0/(1LL<< 7);
94  }
95  if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S32 && (s->dither.output_sample_bits&31)) scale = 1;
96  if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1<<16;
97  if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1<<24;
98  if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1<<8;
99 
100  scale *= s->dither.scale;
101 
102  if (out_fmt == AV_SAMPLE_FMT_S32 && s->dither.output_sample_bits)
103  scale *= 1<<(32-s->dither.output_sample_bits);
104 
105  if (scale == 0) {
106  s->dither.method = 0;
107  return 0;
108  }
109 
110  s->dither.ns_pos = 0;
111  s->dither.noise_scale= scale;
112  s->dither.ns_scale = scale;
113  s->dither.ns_scale_1 = scale ? 1/scale : 0;
114  memset(s->dither.ns_errors, 0, sizeof(s->dither.ns_errors));
115  for (i=0; filters[i].coefs; i++) {
116  const filter_t *f = &filters[i];
117  if (llabs(s->out_sample_rate - f->rate)*20 <= f->rate && f->name == s->dither.method) {
118  int j;
119  s->dither.ns_taps = f->len;
120  for (j=0; j<f->len; j++)
121  s->dither.ns_coeffs[j] = f->coefs[j];
122  s->dither.ns_scale_1 *= 1 - exp(f->gain_cB * M_LN10 * 0.005) * 2 / (1<<(8*av_get_bytes_per_sample(out_fmt)));
123  break;
124  }
125  }
126  if (!filters[i].coefs && s->dither.method > SWR_DITHER_NS) {
127  av_log(s, AV_LOG_WARNING, "Requested noise shaping dither not available at this sampling rate, using triangular hp dither\n");
129  }
130 
131  return 0;
132 }
133 
134 #define TEMPLATE_DITHER_S16
135 #include "dither_template.c"
136 #undef TEMPLATE_DITHER_S16
137 
138 #define TEMPLATE_DITHER_S32
139 #include "dither_template.c"
140 #undef TEMPLATE_DITHER_S32
141 
142 #define TEMPLATE_DITHER_FLT
143 #include "dither_template.c"
144 #undef TEMPLATE_DITHER_FLT
145 
146 #define TEMPLATE_DITHER_DBL
147 #include "dither_template.c"
148 #undef TEMPLATE_DITHER_DBL
float, planar
Definition: samplefmt.h:69
int out_sample_rate
output sample rate
enum AVResampleDitherMethod method
Definition: dither.c:56
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
double, planar
Definition: samplefmt.h:70
float ns_scale
Noise shaping dither scale.
float ns_coeffs[NS_TAPS]
Noise shaping filter coefficients.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define TMP_EXTRA
float ns_errors[SWR_CH_MAX][2 *NS_TAPS]
#define av_cold
Definition: attributes.h:82
AV_SAMPLE_FMT_U8
int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt)
Definition: dither.c:26
#define f(width, name)
Definition: cbs_vp9.c:255
signed 32 bits
Definition: samplefmt.h:62
#define av_log(a,...)
enum SwrDitherType name
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int output_sample_bits
the number of used output bits, needed to scale dither correctly
av_cold int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt)
Definition: dither.c:79
The libswresample context.
simple assert() macros that are a bit more flexible than ISO C assert().
int8_t exp
Definition: eval.c:72
not part of API/ABI
Definition: swresample.h:155
signed 32 bits, planar
Definition: samplefmt.h:68
int32_t
not part of API/ABI
Definition: swresample.h:147
#define s(width, name)
Definition: cbs_vp9.c:257
float ns_scale_1
Noise shaping dither scale^-1.
float noise_scale
Noise scale.
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
double const * coefs
static unsigned int seed
Definition: videogen.c:78
int ns_pos
Noise shaping dither position.
struct DitherContext dither
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
#define M_LN10
Definition: mathematics.h:43
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition: samplefmt.c:75
signed 16 bits
Definition: samplefmt.h:61
#define av_free(p)
int len
static const struct PPFilter filters[]
Definition: postprocess.c:134
signed 16 bits, planar
Definition: samplefmt.h:67
#define av_malloc_array(a, b)
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
int ns_taps
Noise shaping dither taps.
static uint8_t tmp[11]
Definition: aes_ctr.c:26