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 "libavutil/mem.h"
23 #include "swresample_internal.h"
24 
25 #include "noise_shaping_data.c"
26 
27 int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt) {
28  double scale = s->dither.noise_scale;
29 #define TMP_EXTRA 2
30  double *tmp = av_malloc_array(len + TMP_EXTRA, sizeof(double));
31  int i;
32 
33  if (!tmp)
34  return AVERROR(ENOMEM);
35 
36  for(i=0; i<len + TMP_EXTRA; i++){
37  double v;
38  seed = seed* 1664525 + 1013904223;
39 
40  switch(s->dither.method){
41  case SWR_DITHER_RECTANGULAR: v= ((double)seed) / UINT_MAX - 0.5; break;
42  default:
43  av_assert0(s->dither.method < SWR_DITHER_NB);
44  v = ((double)seed) / UINT_MAX;
45  seed = seed*1664525 + 1013904223;
46  v-= ((double)seed) / UINT_MAX;
47  break;
48  }
49  tmp[i] = v;
50  }
51 
52  for(i=0; i<len; i++){
53  double v;
54 
55  switch(s->dither.method){
56  default:
57  av_assert0(s->dither.method < SWR_DITHER_NB);
58  v = tmp[i];
59  break;
61  v = (- tmp[i] + 2*tmp[i+1] - tmp[i+2]) / sqrt(6);
62  break;
63  }
64 
65  v*= scale;
66 
67  switch(noise_fmt){
68  case AV_SAMPLE_FMT_S16P: ((int16_t*)dst)[i] = v; break;
69  case AV_SAMPLE_FMT_S32P: ((int32_t*)dst)[i] = v; break;
70  case AV_SAMPLE_FMT_FLTP: ((float *)dst)[i] = v; break;
71  case AV_SAMPLE_FMT_DBLP: ((double *)dst)[i] = v; break;
72  default: av_assert0(0);
73  }
74  }
75 
76  av_free(tmp);
77  return 0;
78 }
79 
81 {
82  int i;
83  double scale = 0;
84 
85  if (s->dither.method > SWR_DITHER_TRIANGULAR_HIGHPASS && s->dither.method <= SWR_DITHER_NS)
86  return AVERROR(EINVAL);
87 
88  out_fmt = av_get_packed_sample_fmt(out_fmt);
89  in_fmt = av_get_packed_sample_fmt( in_fmt);
90 
91  if(in_fmt == AV_SAMPLE_FMT_FLT || in_fmt == AV_SAMPLE_FMT_DBL){
92  if(out_fmt == AV_SAMPLE_FMT_S32) scale = 1.0/(1LL<<31);
93  if(out_fmt == AV_SAMPLE_FMT_S16) scale = 1.0/(1LL<<15);
94  if(out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1.0/(1LL<< 7);
95  }
96  if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S32 && (s->dither.output_sample_bits&31)) scale = 1;
97  if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1<<16;
98  if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1<<24;
99  if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1<<8;
100 
101  scale *= s->dither.scale;
102 
103  if (out_fmt == AV_SAMPLE_FMT_S32 && s->dither.output_sample_bits)
104  scale *= 1<<(32-s->dither.output_sample_bits);
105 
106  if (scale == 0) {
107  s->dither.method = 0;
108  return 0;
109  }
110 
111  s->dither.ns_pos = 0;
112  s->dither.noise_scale= scale;
113  s->dither.ns_scale = scale;
114  s->dither.ns_scale_1 = scale ? 1/scale : 0;
115  memset(s->dither.ns_errors, 0, sizeof(s->dither.ns_errors));
116  for (i=0; filters[i].coefs; i++) {
117  const filter_t *f = &filters[i];
118  if (llabs(s->out_sample_rate - f->rate)*20 <= f->rate && f->name == s->dither.method) {
119  int j;
120  s->dither.ns_taps = f->len;
121  for (j=0; j<f->len; j++)
122  s->dither.ns_coeffs[j] = f->coefs[j];
123  s->dither.ns_scale_1 *= 1 - exp(f->gain_cB * M_LN10 * 0.005) * 2 / (1<<(8*av_get_bytes_per_sample(out_fmt)));
124  break;
125  }
126  }
127  if (!filters[i].coefs && s->dither.method > SWR_DITHER_NS) {
128  av_log(s, AV_LOG_WARNING, "Requested noise shaping dither not available at this sampling rate, using triangular hp dither\n");
129  s->dither.method = SWR_DITHER_TRIANGULAR_HIGHPASS;
130  }
131 
132  return 0;
133 }
134 
135 #define TEMPLATE_DITHER_S16
136 #include "dither_template.c"
137 #undef TEMPLATE_DITHER_S16
138 
139 #define TEMPLATE_DITHER_S32
140 #include "dither_template.c"
141 #undef TEMPLATE_DITHER_S32
142 
143 #define TEMPLATE_DITHER_FLT
144 #include "dither_template.c"
145 #undef TEMPLATE_DITHER_FLT
146 
147 #define TEMPLATE_DITHER_DBL
148 #include "dither_template.c"
149 #undef TEMPLATE_DITHER_DBL
SWR_DITHER_TRIANGULAR_HIGHPASS
@ SWR_DITHER_TRIANGULAR_HIGHPASS
Definition: swresample.h:152
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:66
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
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:28
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:65
SWR_DITHER_NB
@ SWR_DITHER_NB
not part of API/ABI
Definition: swresample.h:162
avassert.h
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:198
filters
#define filters(fmt, type, inverse, clp, inverset, clip, one, clip_fn, packed)
Definition: af_crystalizer.c:55
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
SWR_DITHER_NS
@ SWR_DITHER_NS
not part of API/ABI
Definition: swresample.h:154
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
filter_t
Definition: noise_shaping_data.c:18
double
double
Definition: af_crystalizer.c:132
exp
int8_t exp
Definition: eval.c:73
seed
static unsigned int seed
Definition: videogen.c:78
f
f
Definition: af_crystalizer.c:122
TMP_EXTRA
#define TMP_EXTRA
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
swresample_internal.h
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:64
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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
AV_SAMPLE_FMT_U8
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition: samplefmt.h:57
swri_get_dither
int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt)
Definition: dither.c:27
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:58
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:80
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:77
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:67
mem.h
M_LN10
#define M_LN10
Definition: mathematics.h:49
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
int32_t
int32_t
Definition: audioconvert.c:56
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:61
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:59
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:60
dither_template.c
SWR_DITHER_RECTANGULAR
@ SWR_DITHER_RECTANGULAR
Definition: swresample.h:150