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:
42  av_assert0(s->dither.method < SWR_DITHER_NB);
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:
56  av_assert0(s->dither.method < SWR_DITHER_NB);
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 
84  if (s->dither.method > SWR_DITHER_TRIANGULAR_HIGHPASS && s->dither.method <= SWR_DITHER_NS)
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");
128  s->dither.method = SWR_DITHER_TRIANGULAR_HIGHPASS;
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
SWR_DITHER_TRIANGULAR_HIGHPASS
@ SWR_DITHER_TRIANGULAR_HIGHPASS
Definition: swresample.h:145
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
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
noise_shaping_data.c
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:68
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1388
filters
#define filters(fmt, inverse, clip, i, c)
Definition: af_crystalizer.c:221
SWR_DITHER_NB
@ SWR_DITHER_NB
not part of API/ABI
Definition: swresample.h:155
avassert.h
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:257
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
SWR_DITHER_NS
@ SWR_DITHER_NS
not part of API/ABI
Definition: swresample.h:147
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
f
#define f(width, name)
Definition: cbs_vp9.c:255
filter_t
Definition: noise_shaping_data.c:18
exp
int8_t exp
Definition: eval.c:72
seed
static unsigned int seed
Definition: videogen.c:78
TMP_EXTRA
#define TMP_EXTRA
swresample_internal.h
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:67
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
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
AV_SAMPLE_FMT_U8
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition: samplefmt.h:60
swri_get_dither
int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt)
Definition: dither.c:26
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:61
len
int len
Definition: vorbis_enc_data.h:426
swri_dither_init
av_cold int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt)
Definition: dither.c:79
av_get_packed_sample_fmt
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
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
M_LN10
#define M_LN10
Definition: mathematics.h:43
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
int32_t
int32_t
Definition: audioconvert.c:56
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:64
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:62
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63
dither_template.c
SWR_DITHER_RECTANGULAR
@ SWR_DITHER_RECTANGULAR
Definition: swresample.h:143