Mercurial > libavcodec.hg
comparison adpcm.c @ 2516:9f17dd9b80c6 libavcodec
macromedia flavour adpcm decoding (used in flv and swf)
author | alex |
---|---|
date | Mon, 21 Feb 2005 19:27:32 +0000 |
parents | 2b75dff01118 |
children | ba8ecddf5598 |
comparison
equal
deleted
inserted
replaced
2515:0a68e8dd1c3b | 2516:9f17dd9b80c6 |
---|---|
15 * You should have received a copy of the GNU Lesser General Public | 15 * You should have received a copy of the GNU Lesser General Public |
16 * License along with this library; if not, write to the Free Software | 16 * License along with this library; if not, write to the Free Software |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 */ | 18 */ |
19 #include "avcodec.h" | 19 #include "avcodec.h" |
20 #include "bitstream.h" | |
20 | 21 |
21 /** | 22 /** |
22 * @file adpcm.c | 23 * @file adpcm.c |
23 * ADPCM codecs. | 24 * ADPCM codecs. |
24 * First version by Francois Revol (revol@free.fr) | 25 * First version by Francois Revol (revol@free.fr) |
106 static int ct_adpcm_table[8] = { | 107 static int ct_adpcm_table[8] = { |
107 0x00E6, 0x00E6, 0x00E6, 0x00E6, | 108 0x00E6, 0x00E6, 0x00E6, 0x00E6, |
108 0x0133, 0x0199, 0x0200, 0x0266 | 109 0x0133, 0x0199, 0x0200, 0x0266 |
109 }; | 110 }; |
110 | 111 |
112 // padded to zero where table size is less then 16 | |
113 static int swf_index_tables[4][16] = { | |
114 /*2*/ { -1, 2 }, | |
115 /*3*/ { -1, -1, 2, 4 }, | |
116 /*4*/ { -1, -1, -1, -1, 2, 4, 6, 8 }, | |
117 /*5*/ { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16 } | |
118 }; | |
119 | |
111 /* end of tables */ | 120 /* end of tables */ |
112 | 121 |
113 typedef struct ADPCMChannelStatus { | 122 typedef struct ADPCMChannelStatus { |
114 int predictor; | 123 int predictor; |
115 short int step_index; | 124 short int step_index; |
127 | 136 |
128 typedef struct ADPCMContext { | 137 typedef struct ADPCMContext { |
129 int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */ | 138 int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */ |
130 ADPCMChannelStatus status[2]; | 139 ADPCMChannelStatus status[2]; |
131 short sample_buffer[32]; /* hold left samples while waiting for right samples */ | 140 short sample_buffer[32]; /* hold left samples while waiting for right samples */ |
141 | |
142 /* SWF only */ | |
143 int nb_bits; | |
144 int nb_samples; | |
132 } ADPCMContext; | 145 } ADPCMContext; |
133 | 146 |
134 /* XXX: implement encoding */ | 147 /* XXX: implement encoding */ |
135 | 148 |
136 #ifdef CONFIG_ENCODERS | 149 #ifdef CONFIG_ENCODERS |
893 src[0] & 0x0F); | 906 src[0] & 0x0F); |
894 } | 907 } |
895 src++; | 908 src++; |
896 } | 909 } |
897 break; | 910 break; |
911 case CODEC_ID_ADPCM_SWF: | |
912 { | |
913 GetBitContext gb; | |
914 int *table; | |
915 int k0, signmask; | |
916 int size = buf_size*8; | |
917 | |
918 init_get_bits(&gb, buf, size); | |
919 | |
920 // first frame, read bits & inital values | |
921 if (!c->nb_bits) | |
922 { | |
923 c->nb_bits = get_bits(&gb, 2)+2; | |
924 // av_log(NULL,AV_LOG_INFO,"nb_bits: %d\n", c->nb_bits); | |
925 } | |
926 | |
927 table = swf_index_tables[c->nb_bits-2]; | |
928 k0 = 1 << (c->nb_bits-2); | |
929 signmask = 1 << (c->nb_bits-1); | |
930 | |
931 while (get_bits_count(&gb) <= size) | |
932 { | |
933 int i; | |
934 | |
935 c->nb_samples++; | |
936 // wrap around at every 4096 samples... | |
937 if ((c->nb_samples & 0xfff) == 1) | |
938 { | |
939 for (i = 0; i <= st; i++) | |
940 { | |
941 *samples++ = c->status[i].predictor = get_sbits(&gb, 16); | |
942 c->status[i].step_index = get_bits(&gb, 6); | |
943 } | |
944 } | |
945 | |
946 // similar to IMA adpcm | |
947 for (i = 0; i <= st; i++) | |
948 { | |
949 int delta = get_bits(&gb, c->nb_bits); | |
950 int step = step_table[c->status[i].step_index]; | |
951 long vpdiff = 0; // vpdiff = (delta+0.5)*step/4 | |
952 int k = k0; | |
953 | |
954 do { | |
955 if (delta & k) | |
956 vpdiff += step; | |
957 step >>= 1; | |
958 k >>= 1; | |
959 } while(k); | |
960 vpdiff += step; | |
961 | |
962 if (delta & signmask) | |
963 c->status[i].predictor -= vpdiff; | |
964 else | |
965 c->status[i].predictor += vpdiff; | |
966 | |
967 c->status[i].step_index += table[delta & (~signmask)]; | |
968 | |
969 c->status[i].step_index = clip(c->status[i].step_index, 0, 88); | |
970 c->status[i].predictor = clip(c->status[i].predictor, -32768, 32767); | |
971 | |
972 *samples++ = c->status[i].predictor; | |
973 } | |
974 } | |
975 | |
976 // src += get_bits_count(&gb)*8; | |
977 src += size; | |
978 | |
979 break; | |
980 } | |
898 default: | 981 default: |
899 return -1; | 982 return -1; |
900 } | 983 } |
901 *data_size = (uint8_t *)samples - (uint8_t *)data; | 984 *data_size = (uint8_t *)samples - (uint8_t *)data; |
902 return src - buf; | 985 return src - buf; |
949 ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); | 1032 ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); |
950 ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); | 1033 ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); |
951 ADPCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); | 1034 ADPCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); |
952 ADPCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); | 1035 ADPCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); |
953 ADPCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct); | 1036 ADPCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct); |
1037 ADPCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf); | |
954 | 1038 |
955 #undef ADPCM_CODEC | 1039 #undef ADPCM_CODEC |