annotate g726.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 351a81a23343
children
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
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 8590
diff changeset
3 * Copyright (c) 2004 Roman Shaposhnik
1791
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"
9428
0dce4fe6e6f3 Rename bitstream.h to get_bits.h.
stefano
parents: 9411
diff changeset
26 #include "get_bits.h"
9411
4cb7c65fc775 Split bitstream.h, put the bitstream writer stuff in the new file
stefano
parents: 9355
diff changeset
27 #include "put_bits.h"
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
28
2135
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
29 /**
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
30 * G.726 11bit float.
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
31 * 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
32 * 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
33 * instead of simply using 32bit integer arithmetic.
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
34 */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
35 typedef struct Float11 {
7052
80ead68858f3 Float11 does not need int, .o file becomes smaller and the code might
michael
parents: 7051
diff changeset
36 uint8_t sign; /**< 1bit sign */
80ead68858f3 Float11 does not need int, .o file becomes smaller and the code might
michael
parents: 7051
diff changeset
37 uint8_t exp; /**< 4bit exponent */
80ead68858f3 Float11 does not need int, .o file becomes smaller and the code might
michael
parents: 7051
diff changeset
38 uint8_t mant; /**< 6bit mantissa */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
39 } Float11;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
40
7042
74c1f1881d1a -0x8000 == 0x8000 with int16
michael
parents: 7040
diff changeset
41 static inline Float11* i2f(int i, Float11* f)
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
42 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
43 f->sign = (i < 0);
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
44 if (f->sign)
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
45 i = -i;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
46 f->exp = av_log2_16bit(i) + !!i;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
47 f->mant = i? (i<<6) >> f->exp : 1<<5;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
48 return f;
1791
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
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
51 static inline int16_t mult(Float11* f1, Float11* f2)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
52 {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
53 int res, exp;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
54
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
55 exp = f1->exp + f2->exp;
7051
4f1331b0d428 simplify
michael
parents: 7050
diff changeset
56 res = (((f1->mant * f2->mant) + 0x30) >> 4);
4f1331b0d428 simplify
michael
parents: 7050
diff changeset
57 res = exp > 19 ? res << (exp - 19) : res >> (19 - exp);
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
58 return (f1->sign ^ f2->sign) ? -res : res;
1791
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
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
61 static inline int sgn(int value)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
62 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
63 return (value < 0) ? -1 : 1;
1791
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
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
66 typedef struct G726Tables {
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
67 const int* quant; /**< quantization table */
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
68 const int16_t* iquant; /**< inverse quantization table */
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
69 const int16_t* W; /**< special table #1 ;-) */
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
70 const uint8_t* F; /**< special table #2 */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
71 } G726Tables;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
72
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
73 typedef struct G726Context {
7071
cbc38c3580da Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents: 7070
diff changeset
74 G726Tables tbls; /**< static tables needed for computation */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
75
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
76 Float11 sr[2]; /**< prev. reconstructed samples */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
77 Float11 dq[6]; /**< prev. difference */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
78 int a[2]; /**< second order predictor coeffs */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
79 int b[6]; /**< sixth order predictor coeffs */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
80 int pk[2]; /**< signs of prev. 2 sez + dq */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
81
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
82 int ap; /**< scale factor control */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
83 int yu; /**< fast scale factor */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
84 int yl; /**< slow scale factor */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
85 int dms; /**< short average magnitude of F[i] */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
86 int dml; /**< long average magnitude of F[i] */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
87 int td; /**< tone detect */
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
88
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
89 int se; /**< estimated signal for the next iteration */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
90 int sez; /**< estimated second order prediction */
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
91 int y; /**< quantizer scaling factor for the next iteration */
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
92 int code_size;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
93 } G726Context;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
94
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
95 static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
96 { 260, INT_MAX };
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
97 static const int16_t iquant_tbl16[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
98 { 116, 365, 365, 116 };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
99 static const int16_t W_tbl16[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
100 { -22, 439, 439, -22 };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
101 static const uint8_t F_tbl16[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
102 { 0, 7, 7, 0 };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
103
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
104 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
105 { 7, 217, 330, INT_MAX };
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
106 static const int16_t iquant_tbl24[] =
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
107 { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
108 static const int16_t W_tbl24[] =
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
109 { -4, 30, 137, 582, 582, 137, 30, -4 };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
110 static const uint8_t F_tbl24[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
111 { 0, 1, 2, 7, 7, 2, 1, 0 };
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
112
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
113 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
114 { -125, 79, 177, 245, 299, 348, 399, INT_MAX };
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
115 static const int16_t iquant_tbl32[] =
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
116 { INT16_MIN, 4, 135, 213, 273, 323, 373, 425,
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
117 425, 373, 323, 273, 213, 135, 4, INT16_MIN };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
118 static const int16_t W_tbl32[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
119 { -12, 18, 41, 64, 112, 198, 355, 1122,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
120 1122, 355, 198, 112, 64, 41, 18, -12};
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
121 static const uint8_t F_tbl32[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
122 { 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
123
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
124 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
125 { -122, -16, 67, 138, 197, 249, 297, 338,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
126 377, 412, 444, 474, 501, 527, 552, INT_MAX };
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
127 static const int16_t iquant_tbl40[] =
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
128 { INT16_MIN, -66, 28, 104, 169, 224, 274, 318,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
129 358, 395, 429, 459, 488, 514, 539, 566,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
130 566, 539, 514, 488, 459, 429, 395, 358,
7059
54e5978dd41a Change iquant tables to int16.
michael
parents: 7058
diff changeset
131 318, 274, 224, 169, 104, 28, -66, INT16_MIN };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
132 static const int16_t W_tbl40[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
133 { 14, 14, 24, 39, 40, 41, 58, 100,
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
134 141, 179, 219, 280, 358, 440, 529, 696,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
135 696, 529, 440, 358, 280, 219, 179, 141,
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
136 100, 58, 41, 40, 39, 24, 14, 14 };
7053
e3ee81021cf1 Use smaller data types for tables.
michael
parents: 7052
diff changeset
137 static const uint8_t F_tbl40[] =
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
138 { 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
139 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
140
6128
9dd54c009d47 Mark the tables in g726.c as constant.
benoit
parents: 4962
diff changeset
141 static const G726Tables G726Tables_pool[] =
7072
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
142 {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 },
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
143 { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 },
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
144 { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 },
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
145 { quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }};
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
146
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
147
2135
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
148 /**
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
149 * Para 4.2.2 page 18: Adaptive quantizer.
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
150 */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
151 static inline uint8_t quant(G726Context* c, int d)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
152 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
153 int sign, exp, i, dln;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
154
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
155 sign = i = 0;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
156 if (d < 0) {
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
157 sign = 1;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
158 d = -d;
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
159 }
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
160 exp = av_log2_16bit(d);
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
161 dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
162
7071
cbc38c3580da Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents: 7070
diff changeset
163 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
164 ++i;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
165
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
166 if (sign)
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
167 i = ~i;
7072
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
168 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
169 i = 0xff;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
170
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
171 return i;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
172 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
173
2135
9a481659d7cb make comments doxygen compatible
michael
parents: 1797
diff changeset
174 /**
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
175 * Para 4.2.3 page 22: Inverse adaptive quantizer.
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
176 */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
177 static inline int16_t inverse_quant(G726Context* c, int i)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
178 {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
179 int dql, dex, dqt;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
180
7071
cbc38c3580da Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents: 7070
diff changeset
181 dql = c->tbls.iquant[i] + (c->y >> 2);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
182 dex = (dql>>7) & 0xf; /* 4bit exponent */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
183 dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */
7058
819e52ba3125 simplify
michael
parents: 7057
diff changeset
184 return (dql < 0) ? 0 : ((dqt<<dex) >> 7);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
185 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
186
7070
3e197f8ee6c6 Does not need to be int16.
michael
parents: 7069
diff changeset
187 static int16_t g726_decode(G726Context* c, int I)
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
188 {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
189 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
190 Float11 f;
7072
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
191 int I_sig= I >> (c->code_size - 1);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
192
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
193 dq = inverse_quant(c, I);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
194
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
195 /* Transition detect */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
196 ylint = (c->yl >> 15);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
197 ylfrac = (c->yl >> 10) & 0x1f;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
198 thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint;
7067
4630168a70d5 1 abs() less
michael
parents: 7066
diff changeset
199 tr= (c->td == 1 && dq > ((3*thr2)>>2));
4630168a70d5 1 abs() less
michael
parents: 7066
diff changeset
200
7069
92bcfa9ba977 Factorize I >> (c->tbls->bits - 1) out.
michael
parents: 7067
diff changeset
201 if (I_sig) /* get the sign */
7067
4630168a70d5 1 abs() less
michael
parents: 7066
diff changeset
202 dq = -dq;
4630168a70d5 1 abs() less
michael
parents: 7066
diff changeset
203 re_signal = c->se + dq;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
204
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
205 /* Update second order predictor coefficient A2 and A1 */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
206 pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
207 dq0 = dq ? sgn(dq) : 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
208 if (tr) {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
209 c->a[0] = 0;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
210 c->a[1] = 0;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
211 for (i=0; i<6; i++)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
212 c->b[i] = 0;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
213 } else {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
214 /* 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
215 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
216
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
217 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
218 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
219 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
220 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
221
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
222 for (i=0; i<6; i++)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
223 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
224 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
225
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
226 /* Update Dq and Sr and Pk */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
227 c->pk[1] = c->pk[0];
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
228 c->pk[0] = pk0 ? pk0 : 1;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
229 c->sr[1] = c->sr[0];
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
230 i2f(re_signal, &c->sr[0]);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
231 for (i=5; i>0; i--)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
232 c->dq[i] = c->dq[i-1];
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
233 i2f(dq, &c->dq[0]);
7069
92bcfa9ba977 Factorize I >> (c->tbls->bits - 1) out.
michael
parents: 7067
diff changeset
234 c->dq[0].sign = I_sig; /* Isn't it crazy ?!?! */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
235
7064
f227dcbd4755 remove unneeded tr == 0
michael
parents: 7063
diff changeset
236 c->td = c->a[1] < -11776;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
237
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
238 /* Update Ap */
7074
6f70dc804076 Do not shift F[I] twice, it is also clearer and smaller now.
michael
parents: 7073
diff changeset
239 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
240 c->dml += (c->tbls.F[I]<<4) + ((- c->dml) >> 7);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
241 if (tr)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
242 c->ap = 256;
7073
33dc1d1705f0 Factorize c->ap += (-c->ap) >> 4 out
michael
parents: 7072
diff changeset
243 else {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
244 c->ap += (-c->ap) >> 4;
7073
33dc1d1705f0 Factorize c->ap += (-c->ap) >> 4 out
michael
parents: 7072
diff changeset
245 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
246 c->ap += 0x20;
33dc1d1705f0 Factorize c->ap += (-c->ap) >> 4 out
michael
parents: 7072
diff changeset
247 }
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
248
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
249 /* Update Yu and Yl */
7071
cbc38c3580da Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents: 7070
diff changeset
250 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
251 c->yl += c->yu + ((-c->yl)>>6);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
252
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
253 /* Next iteration for Y */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
254 al = (c->ap >= 256) ? 1<<6 : c->ap >> 2;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
255 c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
256
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
257 /* Next iteration for SE and SEZ */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
258 c->se = 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
259 for (i=0; i<6; i++)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
260 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
261 c->sez = c->se >> 1;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
262 for (i=0; i<2; i++)
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
263 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
264 c->se >>= 1;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
265
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4520
diff changeset
266 return av_clip(re_signal << 2, -0xffff, 0xffff);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
267 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
268
7047
4b5b586a3dd0 Support decoding of sample_g726.asf.
michael
parents: 7046
diff changeset
269 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
270 {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
271 int i;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
272
7071
cbc38c3580da Copy 4 pointers to avid dozends of ptr dereferences.
michael
parents: 7070
diff changeset
273 c->tbls = G726Tables_pool[index];
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
274 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
275 c->sr[i].mant = 1<<5;
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
276 c->pk[i] = 1;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
277 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
278 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
279 c->dq[i].mant = 1<<5;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
280 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
281 c->yu = 544;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
282 c->yl = 34816;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
283
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
284 c->y = 544;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
285
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
286 return 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
287 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
288
8590
7a463923ecd1 Change semantic of CONFIG_*, HAVE_* and ARCH_*.
aurel
parents: 7782
diff changeset
289 #if CONFIG_ADPCM_G726_ENCODER
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
290 static int16_t g726_encode(G726Context* c, int16_t sig)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
291 {
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
292 uint8_t i;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
293
7072
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
294 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
295 g726_decode(c, i);
4119
85438e10d72d reindentation, patch by From: Steve Lhomme, slhomme divxcorp com
diego
parents: 3947
diff changeset
296 return i;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
297 }
3777
20545fbb6f7c add some #ifdef CONFIG_ENCODERS/DECODERS
mru
parents: 3036
diff changeset
298 #endif
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
299
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
300 /* Interfacing to the libavcodec */
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
301
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6377
diff changeset
302 static av_cold int g726_init(AVCodecContext * avctx)
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
303 {
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
304 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
305 unsigned int index;
a570a1e80400 Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents: 7451
diff changeset
306
a570a1e80400 Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents: 7451
diff changeset
307 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
308 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
309 return -1;
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
a570a1e80400 Prevent a division by 0 in the g726 decoder when the configured samplerate is 0.
diego
parents: 7451
diff changeset
312 index = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate - 2;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
313
7050
ecb7071103af Correct validity checks.
michael
parents: 7049
diff changeset
314 if (avctx->bit_rate % avctx->sample_rate && avctx->codec->encode) {
ecb7071103af Correct validity checks.
michael
parents: 7049
diff changeset
315 av_log(avctx, AV_LOG_ERROR, "Bitrate - Samplerate combination is invalid\n");
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
316 return -1;
1792
7da4bdafe42e use clip() from common.h
michael
parents: 1791
diff changeset
317 }
7049
bb24d15211a4 Print sane error message for channels != 1.
michael
parents: 7048
diff changeset
318 if(avctx->channels != 1){
bb24d15211a4 Print sane error message for channels != 1.
michael
parents: 7048
diff changeset
319 av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
bb24d15211a4 Print sane error message for channels != 1.
michael
parents: 7048
diff changeset
320 return -1;
bb24d15211a4 Print sane error message for channels != 1.
michael
parents: 7048
diff changeset
321 }
7048
167726a95509 Check number of bits so we do not try to use table entries which do not exist.
michael
parents: 7047
diff changeset
322 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
323 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
324 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
325 }
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
326 g726_reset(c, index);
7072
be6f9be3a79d Get rid of G726Tables.bits.
michael
parents: 7071
diff changeset
327 c->code_size = index+2;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
328
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
329 avctx->coded_frame = avcodec_alloc_frame();
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
330 if (!avctx->coded_frame)
4520
9bf957e669f0 This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents: 4119
diff changeset
331 return AVERROR(ENOMEM);
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
332 avctx->coded_frame->key_frame = 1;
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
333
7451
85ab7655ad4d Modify all codecs to report their supported input and output sample format(s).
pross
parents: 7074
diff changeset
334 if (avctx->codec->decode)
85ab7655ad4d Modify all codecs to report their supported input and output sample format(s).
pross
parents: 7074
diff changeset
335 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
336
12488
351a81a23343 Set a constant frame size for encoding G.726 audio.
jbr
parents: 12262
diff changeset
337 /* select a frame size that will end on a byte boundary and have a size of
351a81a23343 Set a constant frame size for encoding G.726 audio.
jbr
parents: 12262
diff changeset
338 approximately 1024 bytes */
351a81a23343 Set a constant frame size for encoding G.726 audio.
jbr
parents: 12262
diff changeset
339 if (avctx->codec->encode)
351a81a23343 Set a constant frame size for encoding G.726 audio.
jbr
parents: 12262
diff changeset
340 avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[index];
351a81a23343 Set a constant frame size for encoding G.726 audio.
jbr
parents: 12262
diff changeset
341
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
342 return 0;
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
343 }
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
344
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6377
diff changeset
345 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
346 {
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
347 av_freep(&avctx->coded_frame);
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
348 return 0;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
349 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
350
8590
7a463923ecd1 Change semantic of CONFIG_*, HAVE_* and ARCH_*.
aurel
parents: 7782
diff changeset
351 #if CONFIG_ADPCM_G726_ENCODER
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
352 static int g726_encode_frame(AVCodecContext *avctx,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
353 uint8_t *dst, int buf_size, void *data)
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
354 {
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
355 G726Context *c = avctx->priv_data;
12262
dde20597f15e Use "const" qualifier for pointers that point to input data of
reimar
parents: 11560
diff changeset
356 const short *samples = data;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
357 PutBitContext pb;
12488
351a81a23343 Set a constant frame size for encoding G.726 audio.
jbr
parents: 12262
diff changeset
358 int i;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
359
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
360 init_put_bits(&pb, dst, 1024*1024);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
361
12488
351a81a23343 Set a constant frame size for encoding G.726 audio.
jbr
parents: 12262
diff changeset
362 for (i = 0; i < avctx->frame_size; i++)
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
363 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
364
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
365 flush_put_bits(&pb);
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
366
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
367 return put_bits_count(&pb)>>3;
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
368 }
3777
20545fbb6f7c add some #ifdef CONFIG_ENCODERS/DECODERS
mru
parents: 3036
diff changeset
369 #endif
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
370
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
371 static int g726_decode_frame(AVCodecContext *avctx,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
372 void *data, int *data_size,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8629
diff changeset
373 AVPacket *avpkt)
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
374 {
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8629
diff changeset
375 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 8629
diff changeset
376 int buf_size = avpkt->size;
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
377 G726Context *c = avctx->priv_data;
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
378 short *samples = data;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
379 GetBitContext gb;
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
380
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
381 init_get_bits(&gb, buf, buf_size * 8);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
382
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
383 while (get_bits_count(&gb) + c->code_size <= buf_size*8)
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
384 *samples++ = g726_decode(c, get_bits(&gb, c->code_size));
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
385
7061
3e51aa540377 Remove the truncated bitstream handling from our g726 decoder.
michael
parents: 7059
diff changeset
386 if(buf_size*8 != get_bits_count(&gb))
3e51aa540377 Remove the truncated bitstream handling from our g726 decoder.
michael
parents: 7059
diff changeset
387 av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n");
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2658
diff changeset
388
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
389 *data_size = (uint8_t*)samples - (uint8_t*)data;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
390 return buf_size;
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
391 }
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
392
8590
7a463923ecd1 Change semantic of CONFIG_*, HAVE_* and ARCH_*.
aurel
parents: 7782
diff changeset
393 #if CONFIG_ADPCM_G726_ENCODER
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
394 AVCodec adpcm_g726_encoder = {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
395 "g726",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10145
diff changeset
396 AVMEDIA_TYPE_AUDIO,
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
397 CODEC_ID_ADPCM_G726,
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
398 sizeof(G726Context),
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
399 g726_init,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
400 g726_encode_frame,
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
401 g726_close,
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
402 NULL,
12488
351a81a23343 Set a constant frame size for encoding G.726 audio.
jbr
parents: 12262
diff changeset
403 .capabilities = CODEC_CAP_SMALL_LAST_FRAME,
10145
7955db355703 Make sample_fmts and channel_layouts compound literals const to reduce size of
reimar
parents: 9428
diff changeset
404 .sample_fmts = (const 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
405 .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
406 };
7782
6efb15a24e91 Replace generic CONFIG_ENCODERS preprocessor conditionals by more specific
diego
parents: 7774
diff changeset
407 #endif
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
408
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
409 AVCodec adpcm_g726_decoder = {
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
410 "g726",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10145
diff changeset
411 AVMEDIA_TYPE_AUDIO,
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
412 CODEC_ID_ADPCM_G726,
7062
fb6038ffd2a9 Get rid of the redundant AVG726Context.
michael
parents: 7061
diff changeset
413 sizeof(G726Context),
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
414 g726_init,
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
415 NULL,
1797
fac680cf3008 * gotta setup coded_frame for encoding. avcodec.h says that for decoding
romansh
parents: 1792
diff changeset
416 g726_close,
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
417 g726_decode_frame,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6710
diff changeset
418 .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
1791
5e5c3d4a1e82 * Initial implementation of the G.726 ADPCM audio codec.
romansh
parents:
diff changeset
419 };