annotate adpcm.c @ 787:4914252c963a libavcodec

postprocessing cleanup: remove opendivx #ifdefs remove rk1 filter remove unused / obsolete stuff add -1,4,2,4,-1 deinterlacing filter (ffmpeg uses that) threadsafe / no more non-const globals some optimizations different strides for Y,U,V possible remove ebx usage (someone really should fix gcc, this is really lame) change the dering filter slightly (tell me if its worse for any files)
author michael
date Mon, 28 Oct 2002 19:30:58 +0000
parents babaca0899f1
children 7fccaa0d699d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
1 /*
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
2 * ADPCM codecs
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
3 * Copyright (c) 2001 Fabrice Bellard.
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
4 *
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
9 *
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
13 * Lesser General Public License for more details.
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
14 *
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
18 */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
19 #include "avcodec.h"
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
20
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
21 /*
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
22 * First version by Francois Revol revol@free.fr
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
23 *
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
24 * Features and limitations:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
25 *
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
26 * Reference documents:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
27 * http://www.pcisys.net/~melanson/codecs/adpcm.txt
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
28 * http://www.geocities.com/SiliconValley/8682/aud3.txt
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
29 * http://openquicktime.sourceforge.net/plugins.htm
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
30 * XAnim sources (xa_codec.c) http://www.rasnaimaging.com/people/lapus/download.html
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
31 * http://www.cs.ucla.edu/~leec/mediabench/applications.html
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
32 * SoX source code http://home.sprynet.com/~cbagwell/sox.html
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
33 */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
34
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
35 #define BLKSIZE 1024
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
36
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
37 #define CLAMP_TO_SHORT(value) \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
38 if (value > 32767) \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
39 value = 32767; \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
40 else if (value < -32768) \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
41 value = -32768; \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
42
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
43 /* step_table[] and index_table[] are from the ADPCM reference source */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
44 /* This is the index table: */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
45 static int index_table[16] = {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
46 -1, -1, -1, -1, 2, 4, 6, 8,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
47 -1, -1, -1, -1, 2, 4, 6, 8,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
48 };
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
49
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
50 /* This is the step table. Note that many programs use slight deviations from
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
51 * this table, but such deviations are negligible:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
52 */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
53 static int step_table[89] = {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
54 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
55 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
56 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
57 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
58 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
59 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
60 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
61 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
62 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
63 };
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
64
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
65 /* Those are for MS-ADPCM */
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
66 /* AdaptationTable[], AdaptCoeff1[], and AdaptCoeff2[] are from libsndfile */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
67 static int AdaptationTable[] = {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
68 230, 230, 230, 230, 307, 409, 512, 614,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
69 768, 614, 512, 409, 307, 230, 230, 230
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
70 };
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
71
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
72 static int AdaptCoeff1[] = {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
73 256, 512, 0, 192, 240, 460, 392
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
74 };
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
75
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
76 static int AdaptCoeff2[] = {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
77 0, -256, 0, 64, 0, -208, -232
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
78 };
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
79
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
80 /* end of tables */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
81
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
82 typedef struct ADPCMChannelStatus {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
83 int predictor;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
84 short int step_index;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
85 int step;
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
86 /* for encoding */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
87 int prev_sample;
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
88
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
89 /* MS version */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
90 short sample1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
91 short sample2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
92 int coeff1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
93 int coeff2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
94 int idelta;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
95 } ADPCMChannelStatus;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
96
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
97 typedef struct ADPCMContext {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
98 int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
99 ADPCMChannelStatus status[2];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
100 short sample_buffer[32]; /* hold left samples while waiting for right samples */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
101 } ADPCMContext;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
102
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
103 /* XXX: implement encoding */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
104
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
105 static int adpcm_encode_init(AVCodecContext *avctx)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
106 {
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
107 if (avctx->channels > 2)
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
108 return -1; /* only stereo or mono =) */
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
109 switch(avctx->codec->id) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
110 case CODEC_ID_ADPCM_IMA_QT:
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
111 fprintf(stderr, "ADPCM: codec admcp_ima_qt unsupported for encoding !\n");
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
112 avctx->frame_size = 64; /* XXX: can multiple of avctx->channels * 64 (left and right blocks are interleaved) */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
113 return -1;
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
114 break;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
115 case CODEC_ID_ADPCM_IMA_WAV:
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
116 avctx->frame_size = (BLKSIZE - 4 * avctx->channels) * 8 / (4 * avctx->channels) + 1; /* each 16 bits sample gives one nibble */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
117 /* and we have 4 bytes per channel overhead */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
118 avctx->block_align = BLKSIZE;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
119 /* seems frame_size isn't taken into account... have to buffer the samples :-( */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
120 break;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
121 case CODEC_ID_ADPCM_MS:
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
122 fprintf(stderr, "ADPCM: codec admcp_ms unsupported for encoding !\n");
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
123 return -1;
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
124 break;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
125 default:
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
126 return -1;
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
127 break;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
128 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
129 return 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
130 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
131
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
132 static int adpcm_encode_close(AVCodecContext *avctx)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
133 {
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
134 /* nothing to free */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
135 return 0;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
136 }
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
137
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
138
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
139 static inline unsigned char adpcm_ima_compress_sample(ADPCMChannelStatus *c, short sample)
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
140 {
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
141 int step_index;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
142 unsigned char nibble;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
143
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
144 int sign = 0; /* sign bit of the nibble (MSB) */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
145 int delta, predicted_delta;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
146
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
147 delta = sample - c->prev_sample;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
148
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
149 if (delta < 0) {
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
150 sign = 1;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
151 delta = -delta;
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
152 }
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
153
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
154 step_index = c->step_index;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
155
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
156 /* nibble = 4 * delta / step_table[step_index]; */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
157 nibble = (delta << 2) / step_table[step_index];
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
158
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
159 if (nibble > 7)
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
160 nibble = 7;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
161
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
162 step_index += index_table[nibble];
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
163 if (step_index < 0)
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
164 step_index = 0;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
165 if (step_index > 88)
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
166 step_index = 88;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
167
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
168 /* what the decoder will find */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
169 predicted_delta = ((step_table[step_index] * nibble) / 4) + (step_table[step_index] / 8);
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
170
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
171 if (sign)
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
172 c->prev_sample -= predicted_delta;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
173 else
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
174 c->prev_sample += predicted_delta;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
175
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
176 CLAMP_TO_SHORT(c->prev_sample);
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
177
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
178
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
179 nibble += sign << 3; /* sign * 8 */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
180
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
181 /* save back */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
182 c->step_index = step_index;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
183
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
184 return nibble;
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
185 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
186
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
187 static int adpcm_encode_frame(AVCodecContext *avctx,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
188 unsigned char *frame, int buf_size, void *data)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
189 {
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
190 int n;
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
191 short *samples;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
192 unsigned char *dst;
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
193 ADPCMContext *c = avctx->priv_data;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
194
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
195 dst = frame;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
196 samples = (short *)data;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
197 /* n = (BLKSIZE - 4 * avctx->channels) / (2 * 8 * avctx->channels); */
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
198
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
199 switch(avctx->codec->id) {
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
200 case CODEC_ID_ADPCM_IMA_QT: /* XXX: can't test until we get .mov writer */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
201 break;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
202 case CODEC_ID_ADPCM_IMA_WAV:
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
203 n = avctx->frame_size / 8;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
204 c->status[0].prev_sample = (signed short)samples[0]; /* XXX */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
205 /* c->status[0].step_index = 0; *//* XXX: not sure how to init the state machine */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
206 *dst++ = (c->status[0].prev_sample) & 0xFF; /* little endian */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
207 *dst++ = (c->status[0].prev_sample >> 8) & 0xFF;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
208 *dst++ = (unsigned char)c->status[0].step_index;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
209 *dst++ = 0; /* unknown */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
210 samples++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
211 if (avctx->channels == 2) {
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
212 c->status[1].prev_sample = (signed short)samples[0];
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
213 /* c->status[1].step_index = 0; */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
214 *dst++ = (c->status[1].prev_sample) & 0xFF;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
215 *dst++ = (c->status[1].prev_sample >> 8) & 0xFF;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
216 *dst++ = (unsigned char)c->status[1].step_index;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
217 *dst++ = 0;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
218 samples++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
219 }
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
220
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
221 /* stereo: 4 bytes (8 samples) for left, 4 bytes for right, 4 bytes left, ... */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
222 for (; n>0; n--) {
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
223 *dst = adpcm_ima_compress_sample(&c->status[0], samples[0]) & 0x0F;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
224 *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels]) << 4) & 0xF0;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
225 dst++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
226 *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 2]) & 0x0F;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
227 *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 3]) << 4) & 0xF0;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
228 dst++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
229 *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 4]) & 0x0F;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
230 *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 5]) << 4) & 0xF0;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
231 dst++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
232 *dst = adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 6]) & 0x0F;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
233 *dst |= (adpcm_ima_compress_sample(&c->status[0], samples[avctx->channels * 7]) << 4) & 0xF0;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
234 dst++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
235 /* right channel */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
236 if (avctx->channels == 2) {
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
237 *dst = adpcm_ima_compress_sample(&c->status[1], samples[1]);
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
238 *dst |= adpcm_ima_compress_sample(&c->status[1], samples[3]) << 4;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
239 dst++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
240 *dst = adpcm_ima_compress_sample(&c->status[1], samples[5]);
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
241 *dst |= adpcm_ima_compress_sample(&c->status[1], samples[7]) << 4;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
242 dst++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
243 *dst = adpcm_ima_compress_sample(&c->status[1], samples[9]);
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
244 *dst |= adpcm_ima_compress_sample(&c->status[1], samples[11]) << 4;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
245 dst++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
246 *dst = adpcm_ima_compress_sample(&c->status[1], samples[13]);
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
247 *dst |= adpcm_ima_compress_sample(&c->status[1], samples[15]) << 4;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
248 dst++;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
249 }
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
250 samples += 8 * avctx->channels;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
251 }
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
252 break;
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
253 default:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
254 return -1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
255 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
256 avctx->key_frame = 1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
257 return dst - frame;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
258 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
259
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
260 static int adpcm_decode_init(AVCodecContext * avctx)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
261 {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
262 ADPCMContext *c = avctx->priv_data;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
263
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
264 c->channel = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
265 c->status[0].predictor = c->status[1].predictor = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
266 c->status[0].step_index = c->status[1].step_index = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
267 c->status[0].step = c->status[1].step = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
268
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
269 switch(avctx->codec->id) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
270 default:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
271 break;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
272 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
273 return 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
274 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
275
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
276 static inline short adpcm_ima_expand_nibble(ADPCMChannelStatus *c, char nibble)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
277 {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
278 int step_index;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
279 int predictor;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
280 int sign, delta, diff, step;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
281
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
282 predictor = c->predictor;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
283 step_index = c->step_index + index_table[(unsigned)nibble];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
284 if (step_index < 0) step_index = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
285 if (step_index > 88) step_index = 88;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
286
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
287 step = c->step;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
288
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
289 /*
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
290 diff = ((signed)((nibble & 0x08)?(nibble | 0xF0):(nibble)) + 0.5) * step / 4;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
291 predictor += diff;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
292 */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
293 sign = nibble & 8;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
294 delta = nibble & 7;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
295 diff = step >> 3;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
296 if (delta & 4) diff += step;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
297 if (delta & 2) diff += step >> 1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
298 if (delta & 1) diff += step >> 2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
299 if (sign) predictor -= diff;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
300 else predictor += diff;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
301
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
302 CLAMP_TO_SHORT(predictor);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
303 c->predictor = predictor;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
304 c->step_index = step_index;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
305 c->step = step_table[step_index];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
306
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
307 return (short)predictor;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
308 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
309
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
310 static inline short adpcm_ms_expand_nibble(ADPCMChannelStatus *c, char nibble)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
311 {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
312 int predictor;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
313
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
314 predictor = (((c->sample1) * (c->coeff1)) + ((c->sample2) * (c->coeff2))) / 256;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
315 predictor += (signed)((nibble & 0x08)?(nibble - 0x10):(nibble)) * c->idelta;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
316 CLAMP_TO_SHORT(predictor);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
317
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
318 c->sample2 = c->sample1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
319 c->sample1 = predictor;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
320 c->idelta = (AdaptationTable[(int)nibble] * c->idelta) / 256;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
321 if (c->idelta < 16) c->idelta = 16;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
322
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
323 return (short)predictor;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
324 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
325
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
326 static int adpcm_decode_frame(AVCodecContext *avctx,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
327 void *data, int *data_size,
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
328 UINT8 *buf, int buf_size)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
329 {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
330 ADPCMContext *c = avctx->priv_data;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
331 ADPCMChannelStatus *cs;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
332 int n, m, channel;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
333 int block_predictor[2];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
334 short *samples;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
335 UINT8 *src;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
336 int st; /* stereo */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
337
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
338 samples = data;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
339 src = buf;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
340
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
341 st = avctx->channels == 2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
342
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
343 switch(avctx->codec->id) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
344 case CODEC_ID_ADPCM_IMA_QT:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
345 n = (buf_size - 2);/* >> 2*avctx->channels;*/
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
346 channel = c->channel;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
347 cs = &(c->status[channel]);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
348 /* (pppppp) (piiiiiii) */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
349
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
350 /* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor value */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
351 cs->predictor = (*src++) << 8;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
352 cs->predictor |= (*src & 0x80);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
353 cs->predictor &= 0xFF80;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
354
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
355 /* sign extension */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
356 if(cs->predictor & 0x8000)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
357 cs->predictor -= 0x10000;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
358
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
359 CLAMP_TO_SHORT(cs->predictor);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
360
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
361 cs->step_index = (*src++) & 0x7F;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
362
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
363 if (cs->step_index > 88) fprintf(stderr, "ERROR: step_index = %i\n", cs->step_index);
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
364 if (cs->step_index > 88) cs->step_index = 88;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
365
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
366 cs->step = step_table[cs->step_index];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
367
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
368 if (st && channel)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
369 samples++;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
370
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
371 *samples++ = cs->predictor;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
372 samples += st;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
373
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
374 for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
375 *samples = adpcm_ima_expand_nibble(cs, src[0] & 0x0F);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
376 samples += avctx->channels;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
377 *samples = adpcm_ima_expand_nibble(cs, (src[0] >> 4) & 0x0F);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
378 samples += avctx->channels;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
379 src ++;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
380 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
381
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
382 if(st) { /* handle stereo interlacing */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
383 c->channel = (channel + 1) % 2; /* we get one packet for left, then one for right data */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
384 if(channel == 0) { /* wait for the other packet before outputing anything */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
385 *data_size = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
386 return src - buf;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
387 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
388 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
389 break;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
390 case CODEC_ID_ADPCM_IMA_WAV:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
391 if (buf_size > BLKSIZE) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
392 if (avctx->block_align != 0)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
393 buf_size = avctx->block_align;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
394 else
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
395 buf_size = BLKSIZE;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
396 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
397 n = buf_size - 4 * avctx->channels;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
398 cs = &(c->status[0]);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
399 cs->predictor = (*src++) & 0x0FF;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
400 cs->predictor |= ((*src++) << 8) & 0x0FF00;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
401 if(cs->predictor & 0x8000)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
402 cs->predictor -= 0x10000;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
403 CLAMP_TO_SHORT(cs->predictor);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
404
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
405 *samples++ = cs->predictor;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
406
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
407 cs->step_index = *src++;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
408 if (cs->step_index < 0) cs->step_index = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
409 if (cs->step_index > 88) cs->step_index = 88;
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
410 if (*src++) fprintf(stderr, "unused byte should be null !!\n"); /* unused */
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
411
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
412 if (st) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
413 cs = &(c->status[1]);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
414 cs->predictor = (*src++) & 0x0FF;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
415 cs->predictor |= ((*src++) << 8) & 0x0FF00;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
416 if(cs->predictor & 0x8000)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
417 cs->predictor -= 0x10000;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
418 CLAMP_TO_SHORT(cs->predictor);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
419
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
420 *samples++ = cs->predictor;
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
421
573
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
422 cs->step_index = *src++;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
423 if (cs->step_index < 0) cs->step_index = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
424 if (cs->step_index > 88) cs->step_index = 88;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
425 src++; /* unused */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
426 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
427 cs = &(c->status[0]);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
428
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
429
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
430 for(m=3; n>0; n--, m--) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
431 *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] & 0x0F);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
432 if (st)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
433 *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[4] & 0x0F);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
434 *samples++ = adpcm_ima_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
435 if (st)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
436 *samples++ = adpcm_ima_expand_nibble(&c->status[1], (src[4] >> 4) & 0x0F);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
437 src ++;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
438 if (st && !m) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
439 m=3;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
440 src+=4;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
441 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
442 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
443 break;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
444 case CODEC_ID_ADPCM_MS:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
445
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
446 if (buf_size > BLKSIZE) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
447 if (avctx->block_align != 0)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
448 buf_size = avctx->block_align;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
449 else
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
450 buf_size = BLKSIZE;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
451 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
452 n = buf_size - 7 * avctx->channels;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
453 if (n < 0)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
454 return -1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
455 block_predictor[0] = (*src++); /* should be bound */
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
456 block_predictor[0] = (block_predictor[0] < 0)?(0):((block_predictor[0] > 7)?(7):(block_predictor[0]));
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
457 block_predictor[1] = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
458 if (st)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
459 block_predictor[1] = (*src++);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
460 block_predictor[1] = (block_predictor[1] < 0)?(0):((block_predictor[1] > 7)?(7):(block_predictor[1]));
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
461 c->status[0].idelta = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
462 if (c->status[0].idelta & 0x08000)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
463 c->status[0].idelta -= 0x10000;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
464 src+=2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
465 if (st)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
466 c->status[1].idelta = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
467 if (st && c->status[1].idelta & 0x08000)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
468 c->status[1].idelta |= 0xFFFF0000;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
469 if (st)
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
470 src+=2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
471 c->status[0].coeff1 = AdaptCoeff1[block_predictor[0]];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
472 c->status[0].coeff2 = AdaptCoeff2[block_predictor[0]];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
473 c->status[1].coeff1 = AdaptCoeff1[block_predictor[1]];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
474 c->status[1].coeff2 = AdaptCoeff2[block_predictor[1]];
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
475
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
476 c->status[0].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
477 src+=2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
478 if (st) c->status[1].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
479 if (st) src+=2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
480 c->status[0].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
481 src+=2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
482 if (st) c->status[1].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
483 if (st) src+=2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
484
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
485 *samples++ = c->status[0].sample1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
486 if (st) *samples++ = c->status[1].sample1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
487 *samples++ = c->status[0].sample2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
488 if (st) *samples++ = c->status[1].sample2;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
489 for(;n>0;n--) {
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
490 *samples++ = adpcm_ms_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
491 *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
492 src ++;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
493 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
494 break;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
495 default:
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
496 *data_size = 0;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
497 return -1;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
498 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
499 *data_size = (UINT8 *)samples - (UINT8 *)data;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
500 return src - buf;
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
501 }
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
502
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
503 #define ADPCM_CODEC(id, name) \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
504 AVCodec name ## _encoder = { \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
505 #name, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
506 CODEC_TYPE_AUDIO, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
507 id, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
508 sizeof(ADPCMContext), \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
509 adpcm_encode_init, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
510 adpcm_encode_frame, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
511 adpcm_encode_close, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
512 NULL, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
513 }; \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
514 AVCodec name ## _decoder = { \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
515 #name, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
516 CODEC_TYPE_AUDIO, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
517 id, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
518 sizeof(ADPCMContext), \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
519 adpcm_decode_init, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
520 NULL, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
521 NULL, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
522 adpcm_decode_frame, \
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
523 };
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
524
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
525 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
526 ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
527 ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
528
b0f52172f4c5 beos/mov/adpcm patch by Franois Revol <revol at free dot fr>
michaelni
parents:
diff changeset
529 #undef ADPCM_CODEC
577
babaca0899f1 adpcm encoding patch by Franois Revol <revol at free dot fr>
michaelni
parents: 573
diff changeset
530