annotate g726.c @ 8520:a0164882aa38 libavcodec

Generic metadata API. avi is updated as example. No version bump, the API still might change slightly ... No update to ffmpeg.c as requested by aurel.
author michael
date Sun, 04 Jan 2009 18:48:37 +0000
parents 6efb15a24e91
children 7a463923ecd1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
1 /*
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
28 /**
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
29 * G.726 11bit float.
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
74c1f1881d1a -0x8000 == 0x8000 with int16
michael
parents: 7040
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
52 int res, exp;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
53
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
54 exp = f1->exp + f2->exp;
7051
4f1331b0d428 simplify
michael
parents: 7050
diff changeset
55 res = (((f1->mant * f2->mant) + 0x30) >> 4);
4f1331b0d428 simplify
michael
parents: 7050
diff changeset
56 res = exp > 19 ? res << (exp - 19) : res >> (19 - exp);
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
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
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
66 const int* quant; /**< quantization table */
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
67 const int16_t* iquant; /**< inverse quantization table */
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
68 const int16_t* W; /**< special table #1 ;-) */
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
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
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
94 static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
95 { 260, INT_MAX };
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
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
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
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
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
102
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
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
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
105 static const int16_t iquant_tbl24[] =
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
106 { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
107 static const int16_t W_tbl24[] =
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
108 { -4, 30, 137, 582, 582, 137, 30, -4 };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
111
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
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
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
114 static const int16_t iquant_tbl32[] =
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
115 { INT16_MIN, 4, 135, 213, 273, 323, 373, 425,
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
116 425, 373, 323, 273, 213, 135, 4, INT16_MIN };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
119 1122, 355, 198, 112, 64, 41, 18, -12};
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
122
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
125 377, 412, 444, 474, 501, 527, 552, INT_MAX };
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
126 static const int16_t iquant_tbl40[] =
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
127 { INT16_MIN, -66, 28, 104, 169, 224, 274, 318,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
128 358, 395, 429, 459, 488, 514, 539, 566,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
129 566, 539, 514, 488, 459, 429, 395, 358,
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
130 318, 274, 224, 169, 104, 28, -66, INT16_MIN };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
133 141, 179, 219, 280, 358, 440, 529, 696,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
134 696, 529, 440, 358, 280, 219, 179, 141,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
135 100, 58, 41, 40, 39, 24, 14, 14 };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
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
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
140 static const G726Tables G726Tables_pool[] =
7072
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
141 {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 },
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
142 { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 },
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
143 { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 },
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
144 { quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }};
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
145
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
146
2135
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
147 /**
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
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
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
819e52ba3125 simplify
michael
parents: 7057
diff changeset
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
3e197f8ee6c6 Does not need to be int16.
michael
parents: 7069
diff changeset
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
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
190 int I_sig= I >> (c->code_size - 1);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
4630168a70d5 1 abs() less
michael
parents: 7066
diff changeset
198 tr= (c->td == 1 && dq > ((3*thr2)>>2));
4630168a70d5 1 abs() less
michael
parents: 7066
diff changeset
199
7069
92bcfa9ba977 Factorize I >> (c->tbls->bits - 1) out.
michael
parents: 7067
diff changeset
200 if (I_sig) /* get the sign */
7067
4630168a70d5 1 abs() less
michael
parents: 7066
diff changeset
201 dq = -dq;
4630168a70d5 1 abs() less
michael
parents: 7066
diff changeset
202 re_signal = c->se + dq;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
213 /* This is a bit crazy, but it really is +255 not +256 */
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
214 fa1 = av_clip((-c->a[0]*c->pk[0]*pk0)>>5, -256, 255);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
215
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
216 c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7);
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
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
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
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
92bcfa9ba977 Factorize I >> (c->tbls->bits - 1) out.
michael
parents: 7067
diff changeset
233 c->dq[0].sign = I_sig; /* Isn't it crazy ?!?! */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
234
7064
f227dcbd4755 remove unneeded tr == 0
michael
parents: 7063
diff changeset
235 c->td = c->a[1] < -11776;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
240 if (tr)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
241 c->ap = 256;
7073
33dc1d1705f0 Factorize c->ap += (-c->ap) >> 4 out
michael
parents: 7072
diff changeset
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
33dc1d1705f0 Factorize c->ap += (-c->ap) >> 4 out
michael
parents: 7072
diff changeset
244 if (c->y <= 1535 || c->td || abs((c->dms << 2) - c->dml) >= (c->dml >> 3))
33dc1d1705f0 Factorize c->ap += (-c->ap) >> 4 out
michael
parents: 7072
diff changeset
245 c->ap += 0x20;
33dc1d1705f0 Factorize c->ap += (-c->ap) >> 4 out
michael
parents: 7072
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
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
4b5b586a3dd0 Support decoding of sample_g726.asf.
michael
parents: 7046
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
292
7072
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
293 i = quant(c, sig/4 - c->se) & ((1<<c->code_size) - 1);
7057
2de55b561147 Get rid of useless wrapper function.
michael
parents: 7056
diff changeset
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
20545fbb6f7c add some #ifdef CONFIG_ENCODERS/DECODERS
mru
parents: 3036
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
312
7050
ecb7071103af Correct validity checks.
michael
parents: 7049
diff changeset
313 if (avctx->bit_rate % avctx->sample_rate && avctx->codec->encode) {
ecb7071103af Correct validity checks.
michael
parents: 7049
diff changeset
314 av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n");
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
315 return -1;
1792
7da4bdafe42e use clip() from common.h
michael
parents: 1791
diff changeset
316 }
7049
bb24d15211a4 Print sane error message for channels != 1.
michael
parents: 7048
diff changeset
317 if(avctx->channels != 1){
bb24d15211a4 Print sane error message for channels != 1.
michael
parents: 7048
diff changeset
318 av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
bb24d15211a4 Print sane error message for channels != 1.
michael
parents: 7048
diff changeset
319 return -1;
bb24d15211a4 Print sane error message for channels != 1.
michael
parents: 7048
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
325 g726_reset(c, index);
7072
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
360 return put_bits_count(&pb)>>3;
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
361 }
3777
20545fbb6f7c add some #ifdef CONFIG_ENCODERS/DECODERS
mru
parents: 3036
diff changeset
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
michael
parents: 6128
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
370 GetBitContext gb;
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
375 *samples++ = g726_decode(c, get_bits(&gb, c->code_size));
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
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
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
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 };