OLD | NEW |
1 /* Copyright (c) 2011 Xiph.Org Foundation | 1 /* Copyright (c) 2011 Xiph.Org Foundation |
2 Written by Jean-Marc Valin */ | 2 Written by Jean-Marc Valin */ |
3 /* | 3 /* |
4 Redistribution and use in source and binary forms, with or without | 4 Redistribution and use in source and binary forms, with or without |
5 modification, are permitted provided that the following conditions | 5 modification, are permitted provided that the following conditions |
6 are met: | 6 are met: |
7 | 7 |
8 - Redistributions of source code must retain the above copyright | 8 - Redistributions of source code must retain the above copyright |
9 notice, this list of conditions and the following disclaimer. | 9 notice, this list of conditions and the following disclaimer. |
10 | 10 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 145 |
146 typedef void (*opus_copy_channel_out_func)( | 146 typedef void (*opus_copy_channel_out_func)( |
147 void *dst, | 147 void *dst, |
148 int dst_stride, | 148 int dst_stride, |
149 int dst_channel, | 149 int dst_channel, |
150 const opus_val16 *src, | 150 const opus_val16 *src, |
151 int src_stride, | 151 int src_stride, |
152 int frame_size | 152 int frame_size |
153 ); | 153 ); |
154 | 154 |
| 155 static int opus_multistream_packet_validate(const unsigned char *data, |
| 156 opus_int32 len, int nb_streams, opus_int32 Fs) |
| 157 { |
| 158 int s; |
| 159 int count; |
| 160 unsigned char toc; |
| 161 opus_int16 size[48]; |
| 162 int samples=0; |
| 163 opus_int32 packet_offset; |
| 164 |
| 165 for (s=0;s<nb_streams;s++) |
| 166 { |
| 167 int tmp_samples; |
| 168 if (len<=0) |
| 169 return OPUS_INVALID_PACKET; |
| 170 count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL, |
| 171 size, NULL, &packet_offset); |
| 172 if (count<0) |
| 173 return count; |
| 174 tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs); |
| 175 if (s!=0 && samples != tmp_samples) |
| 176 return OPUS_INVALID_PACKET; |
| 177 samples = tmp_samples; |
| 178 data += packet_offset; |
| 179 len -= packet_offset; |
| 180 } |
| 181 return samples; |
| 182 } |
| 183 |
155 static int opus_multistream_decode_native( | 184 static int opus_multistream_decode_native( |
156 OpusMSDecoder *st, | 185 OpusMSDecoder *st, |
157 const unsigned char *data, | 186 const unsigned char *data, |
158 opus_int32 len, | 187 opus_int32 len, |
159 void *pcm, | 188 void *pcm, |
160 opus_copy_channel_out_func copy_channel_out, | 189 opus_copy_channel_out_func copy_channel_out, |
161 int frame_size, | 190 int frame_size, |
162 int decode_fec, | 191 int decode_fec, |
163 int soft_clip | 192 int soft_clip |
164 ) | 193 ) |
(...skipping 11 matching lines...) Expand all Loading... |
176 opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)); | 205 opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)); |
177 frame_size = IMIN(frame_size, Fs/25*3); | 206 frame_size = IMIN(frame_size, Fs/25*3); |
178 ALLOC(buf, 2*frame_size, opus_val16); | 207 ALLOC(buf, 2*frame_size, opus_val16); |
179 ptr = (char*)st + align(sizeof(OpusMSDecoder)); | 208 ptr = (char*)st + align(sizeof(OpusMSDecoder)); |
180 coupled_size = opus_decoder_get_size(2); | 209 coupled_size = opus_decoder_get_size(2); |
181 mono_size = opus_decoder_get_size(1); | 210 mono_size = opus_decoder_get_size(1); |
182 | 211 |
183 if (len==0) | 212 if (len==0) |
184 do_plc = 1; | 213 do_plc = 1; |
185 if (len < 0) | 214 if (len < 0) |
| 215 { |
| 216 RESTORE_STACK; |
186 return OPUS_BAD_ARG; | 217 return OPUS_BAD_ARG; |
| 218 } |
187 if (!do_plc && len < 2*st->layout.nb_streams-1) | 219 if (!do_plc && len < 2*st->layout.nb_streams-1) |
| 220 { |
| 221 RESTORE_STACK; |
188 return OPUS_INVALID_PACKET; | 222 return OPUS_INVALID_PACKET; |
| 223 } |
| 224 if (!do_plc) |
| 225 { |
| 226 int ret = opus_multistream_packet_validate(data, len, st->layout.nb_stream
s, Fs); |
| 227 if (ret < 0) |
| 228 { |
| 229 RESTORE_STACK; |
| 230 return ret; |
| 231 } else if (ret > frame_size) |
| 232 { |
| 233 RESTORE_STACK; |
| 234 return OPUS_BUFFER_TOO_SMALL; |
| 235 } |
| 236 } |
189 for (s=0;s<st->layout.nb_streams;s++) | 237 for (s=0;s<st->layout.nb_streams;s++) |
190 { | 238 { |
191 OpusDecoder *dec; | 239 OpusDecoder *dec; |
192 int packet_offset, ret; | 240 int packet_offset, ret; |
193 | 241 |
194 dec = (OpusDecoder*)ptr; | 242 dec = (OpusDecoder*)ptr; |
195 ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(m
ono_size); | 243 ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(m
ono_size); |
196 | 244 |
197 if (!do_plc && len<=0) | 245 if (!do_plc && len<=0) |
198 { | 246 { |
199 RESTORE_STACK; | 247 RESTORE_STACK; |
200 return OPUS_INVALID_PACKET; | 248 return OPUS_INTERNAL_ERROR; |
201 } | 249 } |
202 packet_offset = 0; | 250 packet_offset = 0; |
203 ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=s
t->layout.nb_streams-1, &packet_offset, soft_clip); | 251 ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=s
t->layout.nb_streams-1, &packet_offset, soft_clip); |
204 data += packet_offset; | 252 data += packet_offset; |
205 len -= packet_offset; | 253 len -= packet_offset; |
206 if (ret > frame_size) | |
207 { | |
208 RESTORE_STACK; | |
209 return OPUS_BUFFER_TOO_SMALL; | |
210 } | |
211 if (s>0 && ret != frame_size) | |
212 { | |
213 RESTORE_STACK; | |
214 return OPUS_INVALID_PACKET; | |
215 } | |
216 if (ret <= 0) | 254 if (ret <= 0) |
217 { | 255 { |
218 RESTORE_STACK; | 256 RESTORE_STACK; |
219 return ret; | 257 return ret; |
220 } | 258 } |
221 frame_size = ret; | 259 frame_size = ret; |
222 if (s < st->layout.nb_coupled_streams) | 260 if (s < st->layout.nb_coupled_streams) |
223 { | 261 { |
224 int chan, prev; | 262 int chan, prev; |
225 prev = -1; | 263 prev = -1; |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 bad_arg: | 528 bad_arg: |
491 va_end(ap); | 529 va_end(ap); |
492 return OPUS_BAD_ARG; | 530 return OPUS_BAD_ARG; |
493 } | 531 } |
494 | 532 |
495 | 533 |
496 void opus_multistream_decoder_destroy(OpusMSDecoder *st) | 534 void opus_multistream_decoder_destroy(OpusMSDecoder *st) |
497 { | 535 { |
498 opus_free(st); | 536 opus_free(st); |
499 } | 537 } |
OLD | NEW |