Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * WavPack decoder/encoder common code | ||
3 | * Copyright (c) 2006,2011 Konstantin Shishkov | ||
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 | #ifndef AVCODEC_WAVPACK_H | ||
23 | #define AVCODEC_WAVPACK_H | ||
24 | |||
25 | #include <limits.h> | ||
26 | #include <stdint.h> | ||
27 | #include "libavutil/attributes.h" | ||
28 | #include "libavutil/intmath.h" | ||
29 | |||
30 | #define MAX_TERMS 16 | ||
31 | #define MAX_TERM 8 | ||
32 | |||
33 | #define WV_HEADER_SIZE 32 | ||
34 | |||
35 | #define WV_MONO 0x00000004 | ||
36 | #define WV_JOINT_STEREO 0x00000010 | ||
37 | #define WV_CROSS_DECORR 0x00000020 | ||
38 | #define WV_FLOAT_DATA 0x00000080 | ||
39 | #define WV_INT32_DATA 0x00000100 | ||
40 | #define WV_FALSE_STEREO 0x40000000 | ||
41 | #define WV_DSD_DATA 0x80000000 | ||
42 | |||
43 | #define WV_HYBRID_MODE 0x00000008 | ||
44 | #define WV_HYBRID_SHAPE 0x00000008 | ||
45 | #define WV_HYBRID_BITRATE 0x00000200 | ||
46 | #define WV_HYBRID_BALANCE 0x00000400 | ||
47 | #define WV_INITIAL_BLOCK 0x00000800 | ||
48 | #define WV_FINAL_BLOCK 0x00001000 | ||
49 | |||
50 | #define WV_MONO_DATA (WV_MONO | WV_FALSE_STEREO) | ||
51 | |||
52 | #define WV_SINGLE_BLOCK (WV_INITIAL_BLOCK | WV_FINAL_BLOCK) | ||
53 | |||
54 | #define WV_FLT_SHIFT_ONES 0x01 | ||
55 | #define WV_FLT_SHIFT_SAME 0x02 | ||
56 | #define WV_FLT_SHIFT_SENT 0x04 | ||
57 | #define WV_FLT_ZERO_SENT 0x08 | ||
58 | #define WV_FLT_ZERO_SIGN 0x10 | ||
59 | |||
60 | #define WV_MAX_CHANNELS (1 << 12) | ||
61 | #define WV_MAX_SAMPLES 150000 | ||
62 | |||
63 | enum WP_ID_Flags { | ||
64 | WP_IDF_MASK = 0x3F, | ||
65 | WP_IDF_IGNORE = 0x20, | ||
66 | WP_IDF_ODD = 0x40, | ||
67 | WP_IDF_LONG = 0x80 | ||
68 | }; | ||
69 | |||
70 | enum WP_ID { | ||
71 | WP_ID_DUMMY = 0, | ||
72 | WP_ID_ENCINFO, | ||
73 | WP_ID_DECTERMS, | ||
74 | WP_ID_DECWEIGHTS, | ||
75 | WP_ID_DECSAMPLES, | ||
76 | WP_ID_ENTROPY, | ||
77 | WP_ID_HYBRID, | ||
78 | WP_ID_SHAPING, | ||
79 | WP_ID_FLOATINFO, | ||
80 | WP_ID_INT32INFO, | ||
81 | WP_ID_DATA, | ||
82 | WP_ID_CORR, | ||
83 | WP_ID_EXTRABITS, | ||
84 | WP_ID_CHANINFO, | ||
85 | WP_ID_DSD_DATA, | ||
86 | WP_ID_SAMPLE_RATE = 0x27, | ||
87 | }; | ||
88 | |||
89 | typedef struct Decorr { | ||
90 | int delta; | ||
91 | int value; | ||
92 | int weightA; | ||
93 | int weightB; | ||
94 | int samplesA[MAX_TERM]; | ||
95 | int samplesB[MAX_TERM]; | ||
96 | int sumA; | ||
97 | int sumB; | ||
98 | } Decorr; | ||
99 | |||
100 | typedef struct WvChannel { | ||
101 | int median[3]; | ||
102 | int slow_level, error_limit; | ||
103 | unsigned bitrate_acc, bitrate_delta; | ||
104 | } WvChannel; | ||
105 | |||
106 | // macros for manipulating median values | ||
107 | #define GET_MED(n) ((c->median[n] >> 4) + 1) | ||
108 | #define DEC_MED(n) c->median[n] -= ((int)(c->median[n] + (128U >> (n)) - 2) / (128 >> (n))) * 2U | ||
109 | #define INC_MED(n) c->median[n] += ((int)(c->median[n] + (128U >> (n)) ) / (128 >> (n))) * 5U | ||
110 | |||
111 | // macros for applying weight | ||
112 | #define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \ | ||
113 | if ((samples) && (in)) { \ | ||
114 | if (((samples) ^ (in)) < 0) { \ | ||
115 | (weight) -= (delta); \ | ||
116 | if ((weight) < -1024) \ | ||
117 | (weight) = -1024; \ | ||
118 | } else { \ | ||
119 | (weight) += (delta); \ | ||
120 | if ((weight) > 1024) \ | ||
121 | (weight) = 1024; \ | ||
122 | } \ | ||
123 | } | ||
124 | |||
125 | static const int wv_rates[16] = { | ||
126 | 6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, | ||
127 | 32000, 44100, 48000, 64000, 88200, 96000, 192000, 0 | ||
128 | }; | ||
129 | |||
130 | // exponent table copied from WavPack source | ||
131 | extern const uint8_t ff_wp_exp2_table[256]; | ||
132 | extern const uint8_t ff_wp_log2_table[256]; | ||
133 | |||
134 | 59970751 | static av_always_inline int wp_exp2(int16_t val) | |
135 | { | ||
136 | 59970751 | int res, neg = 0; | |
137 | |||
138 |
2/2✓ Branch 0 taken 3823 times.
✓ Branch 1 taken 59966928 times.
|
59970751 | if (val < 0) { |
139 | 3823 | val = -val; | |
140 | 3823 | neg = 1; | |
141 | } | ||
142 | |||
143 | 59970751 | res = ff_wp_exp2_table[val & 0xFF] | 0x100; | |
144 | 59970751 | val >>= 8; | |
145 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 59970751 times.
|
59970751 | if (val > 31U) |
146 | ✗ | return INT_MIN; | |
147 |
2/2✓ Branch 0 taken 19414139 times.
✓ Branch 1 taken 40556612 times.
|
59970751 | res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val)); |
148 |
2/2✓ Branch 0 taken 3823 times.
✓ Branch 1 taken 59966928 times.
|
59970751 | return neg ? -res : res; |
149 | } | ||
150 | |||
151 | 59878828 | static av_always_inline int wp_log2(uint32_t val) | |
152 | { | ||
153 | int bits; | ||
154 | |||
155 |
2/2✓ Branch 0 taken 2356777 times.
✓ Branch 1 taken 57522051 times.
|
59878828 | if (!val) |
156 | 2356777 | return 0; | |
157 |
2/2✓ Branch 0 taken 4010746 times.
✓ Branch 1 taken 53511305 times.
|
57522051 | if (val == 1) |
158 | 4010746 | return 256; | |
159 | 53511305 | val += val >> 9; | |
160 | 53511305 | bits = av_log2(val) + 1; | |
161 |
2/2✓ Branch 0 taken 27967183 times.
✓ Branch 1 taken 25544122 times.
|
53511305 | if (bits < 9) |
162 | 27967183 | return (bits << 8) + ff_wp_log2_table[(val << (9 - bits)) & 0xFF]; | |
163 | else | ||
164 | 25544122 | return (bits << 8) + ff_wp_log2_table[(val >> (bits - 9)) & 0xFF]; | |
165 | } | ||
166 | |||
167 | #endif /* AVCODEC_WAVPACK_H */ | ||
168 |