opus_multistream_decoder.c (15178B)
1 /* Copyright (c) 2011 Xiph.Org Foundation 2 Written by Jean-Marc Valin */ 3 /* 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions 6 are met: 7 8 - Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 10 11 - Redistributions in binary form must reproduce the above copyright 12 notice, this list of conditions and the following disclaimer in the 13 documentation and/or other materials provided with the distribution. 14 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif 31 32 #include "opus_multistream.h" 33 #include "opus.h" 34 #include "opus_private.h" 35 #include "stack_alloc.h" 36 #include <stdarg.h> 37 #include "float_cast.h" 38 #include "os_support.h" 39 40 /* DECODER */ 41 42 #if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS) 43 static void validate_ms_decoder(OpusMSDecoder *st) 44 { 45 validate_layout(&st->layout); 46 } 47 #define VALIDATE_MS_DECODER(st) validate_ms_decoder(st) 48 #else 49 #define VALIDATE_MS_DECODER(st) 50 #endif 51 52 53 opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams) 54 { 55 int coupled_size; 56 int mono_size; 57 58 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; 59 coupled_size = opus_decoder_get_size(2); 60 mono_size = opus_decoder_get_size(1); 61 return align(sizeof(OpusMSDecoder)) 62 + nb_coupled_streams * align(coupled_size) 63 + (nb_streams-nb_coupled_streams) * align(mono_size); 64 } 65 66 int opus_multistream_decoder_init( 67 OpusMSDecoder *st, 68 opus_int32 Fs, 69 int channels, 70 int streams, 71 int coupled_streams, 72 const unsigned char *mapping 73 ) 74 { 75 int coupled_size; 76 int mono_size; 77 int i, ret; 78 char *ptr; 79 80 if ((channels>255) || (channels<1) || (coupled_streams>streams) || 81 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) 82 return OPUS_BAD_ARG; 83 84 st->layout.nb_channels = channels; 85 st->layout.nb_streams = streams; 86 st->layout.nb_coupled_streams = coupled_streams; 87 88 for (i=0;i<st->layout.nb_channels;i++) 89 st->layout.mapping[i] = mapping[i]; 90 if (!validate_layout(&st->layout)) 91 return OPUS_BAD_ARG; 92 93 ptr = (char*)st + align(sizeof(OpusMSDecoder)); 94 coupled_size = opus_decoder_get_size(2); 95 mono_size = opus_decoder_get_size(1); 96 97 for (i=0;i<st->layout.nb_coupled_streams;i++) 98 { 99 ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2); 100 if(ret!=OPUS_OK)return ret; 101 ptr += align(coupled_size); 102 } 103 for (;i<st->layout.nb_streams;i++) 104 { 105 ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1); 106 if(ret!=OPUS_OK)return ret; 107 ptr += align(mono_size); 108 } 109 return OPUS_OK; 110 } 111 112 113 OpusMSDecoder *opus_multistream_decoder_create( 114 opus_int32 Fs, 115 int channels, 116 int streams, 117 int coupled_streams, 118 const unsigned char *mapping, 119 int *error 120 ) 121 { 122 int ret; 123 OpusMSDecoder *st; 124 if ((channels>255) || (channels<1) || (coupled_streams>streams) || 125 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) 126 { 127 if (error) 128 *error = OPUS_BAD_ARG; 129 return NULL; 130 } 131 st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams)); 132 if (st==NULL) 133 { 134 if (error) 135 *error = OPUS_ALLOC_FAIL; 136 return NULL; 137 } 138 ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); 139 if (error) 140 *error = ret; 141 if (ret != OPUS_OK) 142 { 143 opus_free(st); 144 st = NULL; 145 } 146 return st; 147 } 148 149 static int opus_multistream_packet_validate(const unsigned char *data, 150 opus_int32 len, int nb_streams, opus_int32 Fs) 151 { 152 int s; 153 int count; 154 unsigned char toc; 155 opus_int16 size[48]; 156 int samples=0; 157 opus_int32 packet_offset; 158 159 for (s=0;s<nb_streams;s++) 160 { 161 int tmp_samples; 162 if (len<=0) 163 return OPUS_INVALID_PACKET; 164 count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL, 165 size, NULL, &packet_offset, NULL, NULL); 166 if (count<0) 167 return count; 168 tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs); 169 if (s!=0 && samples != tmp_samples) 170 return OPUS_INVALID_PACKET; 171 samples = tmp_samples; 172 data += packet_offset; 173 len -= packet_offset; 174 } 175 return samples; 176 } 177 178 int opus_multistream_decode_native( 179 OpusMSDecoder *st, 180 const unsigned char *data, 181 opus_int32 len, 182 void *pcm, 183 opus_copy_channel_out_func copy_channel_out, 184 int frame_size, 185 int decode_fec, 186 int soft_clip, 187 void *user_data 188 ) 189 { 190 opus_int32 Fs; 191 int coupled_size; 192 int mono_size; 193 int s, c; 194 char *ptr; 195 int do_plc=0; 196 VARDECL(opus_res, buf); 197 ALLOC_STACK; 198 199 VALIDATE_MS_DECODER(st); 200 if (frame_size <= 0) 201 { 202 RESTORE_STACK; 203 return OPUS_BAD_ARG; 204 } 205 /* Limit frame_size to avoid excessive stack allocations. */ 206 MUST_SUCCEED(opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs))); 207 frame_size = IMIN(frame_size, Fs/25*3); 208 ALLOC(buf, 2*frame_size, opus_res); 209 ptr = (char*)st + align(sizeof(OpusMSDecoder)); 210 coupled_size = opus_decoder_get_size(2); 211 mono_size = opus_decoder_get_size(1); 212 213 if (len==0) 214 do_plc = 1; 215 if (len < 0) 216 { 217 RESTORE_STACK; 218 return OPUS_BAD_ARG; 219 } 220 if (!do_plc && len < 2*st->layout.nb_streams-1) 221 { 222 RESTORE_STACK; 223 return OPUS_INVALID_PACKET; 224 } 225 if (!do_plc) 226 { 227 int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs); 228 if (ret < 0) 229 { 230 RESTORE_STACK; 231 return ret; 232 } else if (ret > frame_size) 233 { 234 RESTORE_STACK; 235 return OPUS_BUFFER_TOO_SMALL; 236 } 237 } 238 for (s=0;s<st->layout.nb_streams;s++) 239 { 240 OpusDecoder *dec; 241 opus_int32 packet_offset; 242 int ret; 243 244 dec = (OpusDecoder*)ptr; 245 ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size); 246 247 if (!do_plc && len<=0) 248 { 249 RESTORE_STACK; 250 return OPUS_INTERNAL_ERROR; 251 } 252 packet_offset = 0; 253 ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip, NULL, 0); 254 if (!do_plc) 255 { 256 data += packet_offset; 257 len -= packet_offset; 258 } 259 if (ret <= 0) 260 { 261 RESTORE_STACK; 262 return ret; 263 } 264 frame_size = ret; 265 if (s < st->layout.nb_coupled_streams) 266 { 267 int chan, prev; 268 prev = -1; 269 /* Copy "left" audio to the channel(s) where it belongs */ 270 while ( (chan = get_left_channel(&st->layout, s, prev)) != -1) 271 { 272 (*copy_channel_out)(pcm, st->layout.nb_channels, chan, 273 buf, 2, frame_size, user_data); 274 prev = chan; 275 } 276 prev = -1; 277 /* Copy "right" audio to the channel(s) where it belongs */ 278 while ( (chan = get_right_channel(&st->layout, s, prev)) != -1) 279 { 280 (*copy_channel_out)(pcm, st->layout.nb_channels, chan, 281 buf+1, 2, frame_size, user_data); 282 prev = chan; 283 } 284 } else { 285 int chan, prev; 286 prev = -1; 287 /* Copy audio to the channel(s) where it belongs */ 288 while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1) 289 { 290 (*copy_channel_out)(pcm, st->layout.nb_channels, chan, 291 buf, 1, frame_size, user_data); 292 prev = chan; 293 } 294 } 295 } 296 /* Handle muted channels */ 297 for (c=0;c<st->layout.nb_channels;c++) 298 { 299 if (st->layout.mapping[c] == 255) 300 { 301 (*copy_channel_out)(pcm, st->layout.nb_channels, c, 302 NULL, 0, frame_size, user_data); 303 } 304 } 305 RESTORE_STACK; 306 return frame_size; 307 } 308 309 #if !defined(DISABLE_FLOAT_API) 310 static void opus_copy_channel_out_float( 311 void *dst, 312 int dst_stride, 313 int dst_channel, 314 const opus_res *src, 315 int src_stride, 316 int frame_size, 317 void *user_data 318 ) 319 { 320 float *float_dst; 321 opus_int32 i; 322 (void)user_data; 323 float_dst = (float*)dst; 324 if (src != NULL) 325 { 326 for (i=0;i<frame_size;i++) 327 float_dst[i*dst_stride+dst_channel] = RES2FLOAT(src[i*src_stride]); 328 } 329 else 330 { 331 for (i=0;i<frame_size;i++) 332 float_dst[i*dst_stride+dst_channel] = 0; 333 } 334 } 335 #endif 336 337 static void opus_copy_channel_out_short( 338 void *dst, 339 int dst_stride, 340 int dst_channel, 341 const opus_res *src, 342 int src_stride, 343 int frame_size, 344 void *user_data 345 ) 346 { 347 opus_int16 *short_dst; 348 opus_int32 i; 349 (void)user_data; 350 short_dst = (opus_int16*)dst; 351 if (src != NULL) 352 { 353 for (i=0;i<frame_size;i++) 354 short_dst[i*dst_stride+dst_channel] = RES2INT16(src[i*src_stride]); 355 } 356 else 357 { 358 for (i=0;i<frame_size;i++) 359 short_dst[i*dst_stride+dst_channel] = 0; 360 } 361 } 362 363 static void opus_copy_channel_out_int24( 364 void *dst, 365 int dst_stride, 366 int dst_channel, 367 const opus_res *src, 368 int src_stride, 369 int frame_size, 370 void *user_data 371 ) 372 { 373 opus_int32 *short_dst; 374 opus_int32 i; 375 (void)user_data; 376 short_dst = (opus_int32*)dst; 377 if (src != NULL) 378 { 379 for (i=0;i<frame_size;i++) 380 short_dst[i*dst_stride+dst_channel] = RES2INT24(src[i*src_stride]); 381 } 382 else 383 { 384 for (i=0;i<frame_size;i++) 385 short_dst[i*dst_stride+dst_channel] = 0; 386 } 387 } 388 389 #ifdef FIXED_POINT 390 #define OPTIONAL_CLIP 0 391 #else 392 #define OPTIONAL_CLIP 1 393 #endif 394 395 int opus_multistream_decode( 396 OpusMSDecoder *st, 397 const unsigned char *data, 398 opus_int32 len, 399 opus_int16 *pcm, 400 int frame_size, 401 int decode_fec 402 ) 403 { 404 return opus_multistream_decode_native(st, data, len, 405 pcm, opus_copy_channel_out_short, frame_size, decode_fec, OPTIONAL_CLIP, NULL); 406 } 407 408 int opus_multistream_decode24( 409 OpusMSDecoder *st, 410 const unsigned char *data, 411 opus_int32 len, 412 opus_int32 *pcm, 413 int frame_size, 414 int decode_fec 415 ) 416 { 417 return opus_multistream_decode_native(st, data, len, 418 pcm, opus_copy_channel_out_int24, frame_size, decode_fec, 0, NULL); 419 } 420 421 #ifndef DISABLE_FLOAT_API 422 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data, 423 opus_int32 len, float *pcm, int frame_size, int decode_fec) 424 { 425 return opus_multistream_decode_native(st, data, len, 426 pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL); 427 } 428 #endif 429 430 int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request, 431 va_list ap) 432 { 433 int coupled_size, mono_size; 434 char *ptr; 435 int ret = OPUS_OK; 436 437 coupled_size = opus_decoder_get_size(2); 438 mono_size = opus_decoder_get_size(1); 439 ptr = (char*)st + align(sizeof(OpusMSDecoder)); 440 switch (request) 441 { 442 case OPUS_GET_BANDWIDTH_REQUEST: 443 case OPUS_GET_SAMPLE_RATE_REQUEST: 444 case OPUS_GET_GAIN_REQUEST: 445 case OPUS_GET_LAST_PACKET_DURATION_REQUEST: 446 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: 447 case OPUS_GET_COMPLEXITY_REQUEST: 448 { 449 OpusDecoder *dec; 450 /* For int32* GET params, just query the first stream */ 451 opus_int32 *value = va_arg(ap, opus_int32*); 452 dec = (OpusDecoder*)ptr; 453 ret = opus_decoder_ctl(dec, request, value); 454 } 455 break; 456 case OPUS_GET_FINAL_RANGE_REQUEST: 457 { 458 int s; 459 opus_uint32 *value = va_arg(ap, opus_uint32*); 460 opus_uint32 tmp; 461 if (!value) 462 { 463 goto bad_arg; 464 } 465 *value = 0; 466 for (s=0;s<st->layout.nb_streams;s++) 467 { 468 OpusDecoder *dec; 469 dec = (OpusDecoder*)ptr; 470 if (s < st->layout.nb_coupled_streams) 471 ptr += align(coupled_size); 472 else 473 ptr += align(mono_size); 474 ret = opus_decoder_ctl(dec, request, &tmp); 475 if (ret != OPUS_OK) break; 476 *value ^= tmp; 477 } 478 } 479 break; 480 case OPUS_RESET_STATE: 481 { 482 int s; 483 for (s=0;s<st->layout.nb_streams;s++) 484 { 485 OpusDecoder *dec; 486 487 dec = (OpusDecoder*)ptr; 488 if (s < st->layout.nb_coupled_streams) 489 ptr += align(coupled_size); 490 else 491 ptr += align(mono_size); 492 ret = opus_decoder_ctl(dec, OPUS_RESET_STATE); 493 if (ret != OPUS_OK) 494 break; 495 } 496 } 497 break; 498 case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST: 499 { 500 int s; 501 opus_int32 stream_id; 502 OpusDecoder **value; 503 stream_id = va_arg(ap, opus_int32); 504 if (stream_id<0 || stream_id >= st->layout.nb_streams) 505 goto bad_arg; 506 value = va_arg(ap, OpusDecoder**); 507 if (!value) 508 { 509 goto bad_arg; 510 } 511 for (s=0;s<stream_id;s++) 512 { 513 if (s < st->layout.nb_coupled_streams) 514 ptr += align(coupled_size); 515 else 516 ptr += align(mono_size); 517 } 518 *value = (OpusDecoder*)ptr; 519 } 520 break; 521 case OPUS_SET_GAIN_REQUEST: 522 case OPUS_SET_COMPLEXITY_REQUEST: 523 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: 524 { 525 int s; 526 /* This works for int32 params */ 527 opus_int32 value = va_arg(ap, opus_int32); 528 for (s=0;s<st->layout.nb_streams;s++) 529 { 530 OpusDecoder *dec; 531 532 dec = (OpusDecoder*)ptr; 533 if (s < st->layout.nb_coupled_streams) 534 ptr += align(coupled_size); 535 else 536 ptr += align(mono_size); 537 ret = opus_decoder_ctl(dec, request, value); 538 if (ret != OPUS_OK) 539 break; 540 } 541 } 542 break; 543 default: 544 ret = OPUS_UNIMPLEMENTED; 545 break; 546 } 547 return ret; 548 bad_arg: 549 return OPUS_BAD_ARG; 550 } 551 552 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) 553 { 554 int ret; 555 va_list ap; 556 va_start(ap, request); 557 ret = opus_multistream_decoder_ctl_va_list(st, request, ap); 558 va_end(ap); 559 return ret; 560 } 561 562 void opus_multistream_decoder_destroy(OpusMSDecoder *st) 563 { 564 opus_free(st); 565 }