Mercurial > libavcodec.hg
annotate g726.c @ 8130:c45366b01126 libavcodec
ARM: fix j_rev_dct_ARM
This is a bugfix for ARMv4 assembly implementation of 'j_rev_dct'
function.
The problem was in the incorrect partially empty row detection. Even
if the first two coefficients in the row were nonzero, it handled this
just like the case with only the first nonzero coefficient.
Now this function produces exactly the same output as the stripped
down reference C version of 'j_rev_dct' (with the nested checks like
'if (d6) { if (d2) { ...' always evaluated as true, avoiding shortcut
branches).
author | mru |
---|---|
date | Wed, 12 Nov 2008 20:23:36 +0000 |
parents | 6efb15a24e91 |
children | 7a463923ecd1 |
rev | line source |
---|---|
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
1 /* |
2967 | 2 * G.726 ADPCM audio codec |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
3 * Copyright (c) 2004 Roman Shaposhnik. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
4 * |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
5 * This is a very straightforward rendition of the G.726 |
2967 | 6 * Section 4 "Computational Details". |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
7 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
8 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
9 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
10 * FFmpeg is free software; you can redistribute it and/or |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
11 * modify it under the terms of the GNU Lesser General Public |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
12 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
13 * version 2.1 of the License, or (at your option) any later version. |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
14 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
15 * FFmpeg is distributed in the hope that it will be useful, |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
18 * Lesser General Public License for more details. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
19 * |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
20 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
21 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
23 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
24 #include <limits.h> |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
25 #include "avcodec.h" |
2398
582e635cfa08
common.c -> bitstream.c (and the single non bitstream func -> utils.c)
michael
parents:
2135
diff
changeset
|
26 #include "bitstream.h" |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
27 |
2135 | 28 /** |
29 * G.726 11bit float. | |
2967 | 30 * G.726 Standard uses rather odd 11bit floating point arithmentic for |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
31 * numerous occasions. It's a mistery to me why they did it this way |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
32 * instead of simply using 32bit integer arithmetic. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
33 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
34 typedef struct Float11 { |
7052
80ead68858f3
Float11 does not need int, .o file becomes smaller and the code might
michael
parents:
7051
diff
changeset
|
35 uint8_t sign; /**< 1bit sign */ |
80ead68858f3
Float11 does not need int, .o file becomes smaller and the code might
michael
parents:
7051
diff
changeset
|
36 uint8_t exp; /**< 4bit exponent */ |
80ead68858f3
Float11 does not need int, .o file becomes smaller and the code might
michael
parents:
7051
diff
changeset
|
37 uint8_t mant; /**< 6bit mantissa */ |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
38 } Float11; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
39 |
7042 | 40 static inline Float11* i2f(int i, Float11* f) |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
41 { |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
42 f->sign = (i < 0); |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
43 if (f->sign) |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
44 i = -i; |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
45 f->exp = av_log2_16bit(i) + !!i; |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
46 f->mant = i? (i<<6) >> f->exp : 1<<5; |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
47 return f; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
48 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
49 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
50 static inline int16_t mult(Float11* f1, Float11* f2) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
51 { |
2979 | 52 int res, exp; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
53 |
2979 | 54 exp = f1->exp + f2->exp; |
7051 | 55 res = (((f1->mant * f2->mant) + 0x30) >> 4); |
56 res = exp > 19 ? res << (exp - 19) : res >> (19 - exp); | |
2979 | 57 return (f1->sign ^ f2->sign) ? -res : res; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
58 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
59 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
60 static inline int sgn(int value) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
61 { |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
62 return (value < 0) ? -1 : 1; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
63 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
64 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
65 typedef struct G726Tables { |
6128 | 66 const int* quant; /**< quantization table */ |
7059 | 67 const int16_t* iquant; /**< inverse quantization table */ |
7053 | 68 const int16_t* W; /**< special table #1 ;-) */ |
69 const uint8_t* F; /**< special table #2 */ | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
70 } G726Tables; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
71 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
72 typedef struct G726Context { |
7071
cbc38c3580da
Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents:
7070
diff
changeset
|
73 G726Tables tbls; /**< static tables needed for computation */ |
2967 | 74 |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
75 Float11 sr[2]; /**< prev. reconstructed samples */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
76 Float11 dq[6]; /**< prev. difference */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
77 int a[2]; /**< second order predictor coeffs */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
78 int b[6]; /**< sixth order predictor coeffs */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
79 int pk[2]; /**< signs of prev. 2 sez + dq */ |
2967 | 80 |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
81 int ap; /**< scale factor control */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
82 int yu; /**< fast scale factor */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
83 int yl; /**< slow scale factor */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
84 int dms; /**< short average magnitude of F[i] */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
85 int dml; /**< long average magnitude of F[i] */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
86 int td; /**< tone detect */ |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
87 |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
88 int se; /**< estimated signal for the next iteration */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
89 int sez; /**< estimated second order prediction */ |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
90 int y; /**< quantizer scaling factor for the next iteration */ |
7062 | 91 int code_size; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
92 } G726Context; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
93 |
6128 | 94 static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ |
2967 | 95 { 260, INT_MAX }; |
7059 | 96 static const int16_t iquant_tbl16[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
97 { 116, 365, 365, 116 }; |
7053 | 98 static const int16_t W_tbl16[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
99 { -22, 439, 439, -22 }; |
7053 | 100 static const uint8_t F_tbl16[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
101 { 0, 7, 7, 0 }; |
2967 | 102 |
6128 | 103 static const int quant_tbl24[] = /**< 24kbit/s 3bits per sample */ |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
104 { 7, 217, 330, INT_MAX }; |
7059 | 105 static const int16_t iquant_tbl24[] = |
106 { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN }; | |
7053 | 107 static const int16_t W_tbl24[] = |
2967 | 108 { -4, 30, 137, 582, 582, 137, 30, -4 }; |
7053 | 109 static const uint8_t F_tbl24[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
110 { 0, 1, 2, 7, 7, 2, 1, 0 }; |
2967 | 111 |
6128 | 112 static const int quant_tbl32[] = /**< 32kbit/s 4bits per sample */ |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
113 { -125, 79, 177, 245, 299, 348, 399, INT_MAX }; |
7059 | 114 static const int16_t iquant_tbl32[] = |
115 { INT16_MIN, 4, 135, 213, 273, 323, 373, 425, | |
116 425, 373, 323, 273, 213, 135, 4, INT16_MIN }; | |
7053 | 117 static const int16_t W_tbl32[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
118 { -12, 18, 41, 64, 112, 198, 355, 1122, |
2979 | 119 1122, 355, 198, 112, 64, 41, 18, -12}; |
7053 | 120 static const uint8_t F_tbl32[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
121 { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 }; |
2967 | 122 |
6128 | 123 static const int quant_tbl40[] = /**< 40kbit/s 5bits per sample */ |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
124 { -122, -16, 67, 138, 197, 249, 297, 338, |
2979 | 125 377, 412, 444, 474, 501, 527, 552, INT_MAX }; |
7059 | 126 static const int16_t iquant_tbl40[] = |
127 { INT16_MIN, -66, 28, 104, 169, 224, 274, 318, | |
2979 | 128 358, 395, 429, 459, 488, 514, 539, 566, |
129 566, 539, 514, 488, 459, 429, 395, 358, | |
7059 | 130 318, 274, 224, 169, 104, 28, -66, INT16_MIN }; |
7053 | 131 static const int16_t W_tbl40[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
132 { 14, 14, 24, 39, 40, 41, 58, 100, |
2979 | 133 141, 179, 219, 280, 358, 440, 529, 696, |
134 696, 529, 440, 358, 280, 219, 179, 141, | |
135 100, 58, 41, 40, 39, 24, 14, 14 }; | |
7053 | 136 static const uint8_t F_tbl40[] = |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
137 { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6, |
2979 | 138 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
139 |
6128 | 140 static const G726Tables G726Tables_pool[] = |
7072 | 141 {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 }, |
142 { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 }, | |
143 { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 }, | |
144 { quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }}; | |
2967 | 145 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
146 |
2135 | 147 /** |
2967 | 148 * Para 4.2.2 page 18: Adaptive quantizer. |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
149 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
150 static inline uint8_t quant(G726Context* c, int d) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
151 { |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
152 int sign, exp, i, dln; |
2967 | 153 |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
154 sign = i = 0; |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
155 if (d < 0) { |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
156 sign = 1; |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
157 d = -d; |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
158 } |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
159 exp = av_log2_16bit(d); |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
160 dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2); |
2967 | 161 |
7071
cbc38c3580da
Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents:
7070
diff
changeset
|
162 while (c->tbls.quant[i] < INT_MAX && c->tbls.quant[i] < dln) |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
163 ++i; |
2967 | 164 |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
165 if (sign) |
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
166 i = ~i; |
7072 | 167 if (c->code_size != 2 && i == 0) /* I'm not sure this is a good idea */ |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
168 i = 0xff; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
169 |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
170 return i; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
171 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
172 |
2135 | 173 /** |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
174 * Para 4.2.3 page 22: Inverse adaptive quantizer. |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
175 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
176 static inline int16_t inverse_quant(G726Context* c, int i) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
177 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
178 int dql, dex, dqt; |
2967 | 179 |
7071
cbc38c3580da
Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents:
7070
diff
changeset
|
180 dql = c->tbls.iquant[i] + (c->y >> 2); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
181 dex = (dql>>7) & 0xf; /* 4bit exponent */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
182 dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */ |
7058 | 183 return (dql < 0) ? 0 : ((dqt<<dex) >> 7); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
184 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
185 |
7070 | 186 static int16_t g726_decode(G726Context* c, int I) |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
187 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
188 int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
189 Float11 f; |
7072 | 190 int I_sig= I >> (c->code_size - 1); |
2967 | 191 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
192 dq = inverse_quant(c, I); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
193 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
194 /* Transition detect */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
195 ylint = (c->yl >> 15); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
196 ylfrac = (c->yl >> 10) & 0x1f; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
197 thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint; |
7067 | 198 tr= (c->td == 1 && dq > ((3*thr2)>>2)); |
199 | |
7069 | 200 if (I_sig) /* get the sign */ |
7067 | 201 dq = -dq; |
202 re_signal = c->se + dq; | |
2967 | 203 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
204 /* Update second order predictor coefficient A2 and A1 */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
205 pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
206 dq0 = dq ? sgn(dq) : 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
207 if (tr) { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
208 c->a[0] = 0; |
2979 | 209 c->a[1] = 0; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
210 for (i=0; i<6; i++) |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
211 c->b[i] = 0; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
212 } else { |
2979 | 213 /* This is a bit crazy, but it really is +255 not +256 */ |
4594 | 214 fa1 = av_clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255); |
2967 | 215 |
2979 | 216 c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7); |
4594 | 217 c->a[1] = av_clip(c->a[1], -12288, 12288); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
218 c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8); |
4594 | 219 c->a[0] = av_clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
220 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
221 for (i=0; i<6; i++) |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
222 c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
223 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
224 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
225 /* Update Dq and Sr and Pk */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
226 c->pk[1] = c->pk[0]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
227 c->pk[0] = pk0 ? pk0 : 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
228 c->sr[1] = c->sr[0]; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
229 i2f(re_signal, &c->sr[0]); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
230 for (i=5; i>0; i--) |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
231 c->dq[i] = c->dq[i-1]; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
232 i2f(dq, &c->dq[0]); |
7069 | 233 c->dq[0].sign = I_sig; /* Isn't it crazy ?!?! */ |
2967 | 234 |
7064 | 235 c->td = c->a[1] < -11776; |
2967 | 236 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
237 /* Update Ap */ |
7074
6f70dc804076
Do not shift F[I] twice, it is also clearer and smaller now.
michael
parents:
7073
diff
changeset
|
238 c->dms += (c->tbls.F[I]<<4) + ((- c->dms) >> 5); |
6f70dc804076
Do not shift F[I] twice, it is also clearer and smaller now.
michael
parents:
7073
diff
changeset
|
239 c->dml += (c->tbls.F[I]<<4) + ((- c->dml) >> 7); |
2967 | 240 if (tr) |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
241 c->ap = 256; |
7073 | 242 else { |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
243 c->ap += (-c->ap) >> 4; |
7073 | 244 if (c->y <= 1535 || c->td || abs((c->dms << 2) - c->dml) >= (c->dml >> 3)) |
245 c->ap += 0x20; | |
246 } | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
247 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
248 /* Update Yu and Yl */ |
7071
cbc38c3580da
Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents:
7070
diff
changeset
|
249 c->yu = av_clip(c->y + c->tbls.W[I] + ((-c->y)>>5), 544, 5120); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
250 c->yl += c->yu + ((-c->yl)>>6); |
2967 | 251 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
252 /* Next iteration for Y */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
253 al = (c->ap >= 256) ? 1<<6 : c->ap >> 2; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
254 c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6; |
2967 | 255 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
256 /* Next iteration for SE and SEZ */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
257 c->se = 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
258 for (i=0; i<6; i++) |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
259 c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
260 c->sez = c->se >> 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
261 for (i=0; i<2; i++) |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
262 c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
263 c->se >>= 1; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
264 |
4594 | 265 return av_clip(re_signal << 2, -0xffff, 0xffff); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
266 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
267 |
7047 | 268 static av_cold int g726_reset(G726Context* c, int index) |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
269 { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
270 int i; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
271 |
7071
cbc38c3580da
Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents:
7070
diff
changeset
|
272 c->tbls = G726Tables_pool[index]; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
273 for (i=0; i<2; i++) { |
7055
d634343b7917
Replace i2f(0) by the actual thing done, gcc is not an optimizing compiler.
michael
parents:
7054
diff
changeset
|
274 c->sr[i].mant = 1<<5; |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
275 c->pk[i] = 1; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
276 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
277 for (i=0; i<6; i++) { |
7055
d634343b7917
Replace i2f(0) by the actual thing done, gcc is not an optimizing compiler.
michael
parents:
7054
diff
changeset
|
278 c->dq[i].mant = 1<<5; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
279 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
280 c->yu = 544; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
281 c->yl = 34816; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
282 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
283 c->y = 544; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
284 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
285 return 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
286 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
287 |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7774
diff
changeset
|
288 #ifdef CONFIG_ADPCM_G726_ENCODER |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
289 static int16_t g726_encode(G726Context* c, int16_t sig) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
290 { |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
291 uint8_t i; |
2967 | 292 |
7072 | 293 i = quant(c, sig/4 - c->se) & ((1<<c->code_size) - 1); |
7057 | 294 g726_decode(c, i); |
4119
85438e10d72d
reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents:
3947
diff
changeset
|
295 return i; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
296 } |
3777 | 297 #endif |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
298 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
299 /* Interfacing to the libavcodec */ |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
300 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6377
diff
changeset
|
301 static av_cold int g726_init(AVCodecContext * avctx) |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
302 { |
7062 | 303 G726Context* c = avctx->priv_data; |
7774
a570a1e80400
Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents:
7451
diff
changeset
|
304 unsigned int index; |
a570a1e80400
Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents:
7451
diff
changeset
|
305 |
a570a1e80400
Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents:
7451
diff
changeset
|
306 if (avctx->sample_rate <= 0) { |
a570a1e80400
Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents:
7451
diff
changeset
|
307 av_log(avctx, AV_LOG_ERROR, "Samplerate is invalid\n"); |
a570a1e80400
Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents:
7451
diff
changeset
|
308 return -1; |
a570a1e80400
Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents:
7451
diff
changeset
|
309 } |
a570a1e80400
Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents:
7451
diff
changeset
|
310 |
a570a1e80400
Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents:
7451
diff
changeset
|
311 index = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2; |
2967 | 312 |
7050 | 313 if (avctx->bit_rate % avctx->sample_rate && avctx->codec->encode) { |
314 av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n"); | |
2979 | 315 return -1; |
1792 | 316 } |
7049 | 317 if(avctx->channels != 1){ |
318 av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n"); | |
319 return -1; | |
320 } | |
7048
167726a95509
Check number of bits so we do not try to use table entries which do not exist.
michael
parents:
7047
diff
changeset
|
321 if(index>3){ |
167726a95509
Check number of bits so we do not try to use table entries which do not exist.
michael
parents:
7047
diff
changeset
|
322 av_log(avctx, AV_LOG_ERROR, "Unsupported number of bits %d\n", index+2); |
167726a95509
Check number of bits so we do not try to use table entries which do not exist.
michael
parents:
7047
diff
changeset
|
323 return -1; |
167726a95509
Check number of bits so we do not try to use table entries which do not exist.
michael
parents:
7047
diff
changeset
|
324 } |
7062 | 325 g726_reset(c, index); |
7072 | 326 c->code_size = index+2; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
327 |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
328 avctx->coded_frame = avcodec_alloc_frame(); |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
329 if (!avctx->coded_frame) |
4520
9bf957e669f0
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
4119
diff
changeset
|
330 return AVERROR(ENOMEM); |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
331 avctx->coded_frame->key_frame = 1; |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
332 |
7451
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7074
diff
changeset
|
333 if (avctx->codec->decode) |
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7074
diff
changeset
|
334 avctx->sample_fmt = SAMPLE_FMT_S16; |
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7074
diff
changeset
|
335 |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
336 return 0; |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
337 } |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
338 |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6377
diff
changeset
|
339 static av_cold int g726_close(AVCodecContext *avctx) |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
340 { |
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
341 av_freep(&avctx->coded_frame); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
342 return 0; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
343 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
344 |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7774
diff
changeset
|
345 #ifdef CONFIG_ADPCM_G726_ENCODER |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
346 static int g726_encode_frame(AVCodecContext *avctx, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
347 uint8_t *dst, int buf_size, void *data) |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
348 { |
7062 | 349 G726Context *c = avctx->priv_data; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
350 short *samples = data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
351 PutBitContext pb; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
352 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
353 init_put_bits(&pb, dst, 1024*1024); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
354 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
355 for (; buf_size; buf_size--) |
7062 | 356 put_bits(&pb, c->code_size, g726_encode(c, *samples++)); |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
357 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
358 flush_put_bits(&pb); |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
359 |
2967 | 360 return put_bits_count(&pb)>>3; |
361 } | |
3777 | 362 #endif |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
363 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
364 static int g726_decode_frame(AVCodecContext *avctx, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
365 void *data, int *data_size, |
6260 | 366 const uint8_t *buf, int buf_size) |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
367 { |
7062 | 368 G726Context *c = avctx->priv_data; |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
369 short *samples = data; |
2967 | 370 GetBitContext gb; |
371 | |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
372 init_get_bits(&gb, buf, buf_size * 8); |
2967 | 373 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
374 while (get_bits_count(&gb) + c->code_size <= buf_size*8) |
7062 | 375 *samples++ = g726_decode(c, get_bits(&gb, c->code_size)); |
2967 | 376 |
7061
3e51aa540377
Remove the truncated bitstream handling from our g726 decoder.
michael
parents:
7059
diff
changeset
|
377 if(buf_size*8 != get_bits_count(&gb)) |
3e51aa540377
Remove the truncated bitstream handling from our g726 decoder.
michael
parents:
7059
diff
changeset
|
378 av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n"); |
2967 | 379 |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
380 *data_size = (uint8_t*)samples - (uint8_t*)data; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
381 return buf_size; |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
382 } |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
383 |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7774
diff
changeset
|
384 #ifdef CONFIG_ADPCM_G726_ENCODER |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
385 AVCodec adpcm_g726_encoder = { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
386 "g726", |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
387 CODEC_TYPE_AUDIO, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
388 CODEC_ID_ADPCM_G726, |
7062 | 389 sizeof(G726Context), |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
390 g726_init, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
391 g726_encode_frame, |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
392 g726_close, |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
393 NULL, |
7451
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7074
diff
changeset
|
394 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
395 .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
396 }; |
7782
6efb15a24e91
Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents:
7774
diff
changeset
|
397 #endif |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
398 |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
399 AVCodec adpcm_g726_decoder = { |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
400 "g726", |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
401 CODEC_TYPE_AUDIO, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
402 CODEC_ID_ADPCM_G726, |
7062 | 403 sizeof(G726Context), |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
404 g726_init, |
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
405 NULL, |
1797
fac680cf3008
* gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents:
1792
diff
changeset
|
406 g726_close, |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
407 g726_decode_frame, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
408 .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), |
1791
5e5c3d4a1e82
* Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff
changeset
|
409 }; |