| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 opus_encoder_destroy(inst->encoder); | 73 opus_encoder_destroy(inst->encoder); |
| 74 free(inst); | 74 free(inst); |
| 75 return 0; | 75 return 0; |
| 76 } else { | 76 } else { |
| 77 return -1; | 77 return -1; |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 | 80 |
| 81 int WebRtcOpus_Encode(OpusEncInst* inst, | 81 int WebRtcOpus_Encode(OpusEncInst* inst, |
| 82 const int16_t* audio_in, | 82 const int16_t* audio_in, |
| 83 int16_t samples, | 83 size_t samples, |
| 84 int16_t length_encoded_buffer, | 84 size_t length_encoded_buffer, |
| 85 uint8_t* encoded) { | 85 uint8_t* encoded) { |
| 86 int res; | 86 int res; |
| 87 | 87 |
| 88 if (samples > 48 * kWebRtcOpusMaxEncodeFrameSizeMs) { | 88 if (samples > 48 * kWebRtcOpusMaxEncodeFrameSizeMs) { |
| 89 return -1; | 89 return -1; |
| 90 } | 90 } |
| 91 | 91 |
| 92 res = opus_encode(inst->encoder, | 92 res = opus_encode(inst->encoder, |
| 93 (const opus_int16*)audio_in, | 93 (const opus_int16*)audio_in, |
| 94 samples, | 94 (int)samples, |
| 95 encoded, | 95 encoded, |
| 96 length_encoded_buffer); | 96 (opus_int32)length_encoded_buffer); |
| 97 | 97 |
| 98 if (res == 1) { | 98 if (res == 1) { |
| 99 // Indicates DTX since the packet has nothing but a header. In principle, | 99 // Indicates DTX since the packet has nothing but a header. In principle, |
| 100 // there is no need to send this packet. However, we do transmit the first | 100 // there is no need to send this packet. However, we do transmit the first |
| 101 // occurrence to let the decoder know that the encoder enters DTX mode. | 101 // occurrence to let the decoder know that the encoder enters DTX mode. |
| 102 if (inst->in_dtx_mode) { | 102 if (inst->in_dtx_mode) { |
| 103 return 0; | 103 return 0; |
| 104 } else { | 104 } else { |
| 105 inst->in_dtx_mode = 1; | 105 inst->in_dtx_mode = 1; |
| 106 return 1; | 106 return 1; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 int16_t WebRtcOpus_DecoderInit(OpusDecInst* inst) { | 253 int16_t WebRtcOpus_DecoderInit(OpusDecInst* inst) { |
| 254 int error = opus_decoder_ctl(inst->decoder, OPUS_RESET_STATE); | 254 int error = opus_decoder_ctl(inst->decoder, OPUS_RESET_STATE); |
| 255 if (error == OPUS_OK) { | 255 if (error == OPUS_OK) { |
| 256 inst->in_dtx_mode = 0; | 256 inst->in_dtx_mode = 0; |
| 257 return 0; | 257 return 0; |
| 258 } | 258 } |
| 259 return -1; | 259 return -1; |
| 260 } | 260 } |
| 261 | 261 |
| 262 /* For decoder to determine if it is to output speech or comfort noise. */ | 262 /* For decoder to determine if it is to output speech or comfort noise. */ |
| 263 static int16_t DetermineAudioType(OpusDecInst* inst, int16_t encoded_bytes) { | 263 static int16_t DetermineAudioType(OpusDecInst* inst, size_t encoded_bytes) { |
| 264 // Audio type becomes comfort noise if |encoded_byte| is 1 and keeps | 264 // Audio type becomes comfort noise if |encoded_byte| is 1 and keeps |
| 265 // to be so if the following |encoded_byte| are 0 or 1. | 265 // to be so if the following |encoded_byte| are 0 or 1. |
| 266 if (encoded_bytes == 0 && inst->in_dtx_mode) { | 266 if (encoded_bytes == 0 && inst->in_dtx_mode) { |
| 267 return 2; // Comfort noise. | 267 return 2; // Comfort noise. |
| 268 } else if (encoded_bytes == 1) { | 268 } else if (encoded_bytes == 1) { |
| 269 inst->in_dtx_mode = 1; | 269 inst->in_dtx_mode = 1; |
| 270 return 2; // Comfort noise. | 270 return 2; // Comfort noise. |
| 271 } else { | 271 } else { |
| 272 inst->in_dtx_mode = 0; | 272 inst->in_dtx_mode = 0; |
| 273 return 0; // Speech. | 273 return 0; // Speech. |
| 274 } | 274 } |
| 275 } | 275 } |
| 276 | 276 |
| 277 /* |frame_size| is set to maximum Opus frame size in the normal case, and | 277 /* |frame_size| is set to maximum Opus frame size in the normal case, and |
| 278 * is set to the number of samples needed for PLC in case of losses. | 278 * is set to the number of samples needed for PLC in case of losses. |
| 279 * It is up to the caller to make sure the value is correct. */ | 279 * It is up to the caller to make sure the value is correct. */ |
| 280 static int DecodeNative(OpusDecInst* inst, const uint8_t* encoded, | 280 static int DecodeNative(OpusDecInst* inst, const uint8_t* encoded, |
| 281 int16_t encoded_bytes, int frame_size, | 281 size_t encoded_bytes, int frame_size, |
| 282 int16_t* decoded, int16_t* audio_type, int decode_fec) { | 282 int16_t* decoded, int16_t* audio_type, int decode_fec) { |
| 283 int res = opus_decode(inst->decoder, encoded, encoded_bytes, | 283 int res = opus_decode(inst->decoder, encoded, (opus_int32)encoded_bytes, |
| 284 (opus_int16*)decoded, frame_size, decode_fec); | 284 (opus_int16*)decoded, frame_size, decode_fec); |
| 285 | 285 |
| 286 if (res <= 0) | 286 if (res <= 0) |
| 287 return -1; | 287 return -1; |
| 288 | 288 |
| 289 *audio_type = DetermineAudioType(inst, encoded_bytes); | 289 *audio_type = DetermineAudioType(inst, encoded_bytes); |
| 290 | 290 |
| 291 return res; | 291 return res; |
| 292 } | 292 } |
| 293 | 293 |
| 294 int WebRtcOpus_Decode(OpusDecInst* inst, const uint8_t* encoded, | 294 int WebRtcOpus_Decode(OpusDecInst* inst, const uint8_t* encoded, |
| 295 int16_t encoded_bytes, int16_t* decoded, | 295 size_t encoded_bytes, int16_t* decoded, |
| 296 int16_t* audio_type) { | 296 int16_t* audio_type) { |
| 297 int decoded_samples; | 297 int decoded_samples; |
| 298 | 298 |
| 299 if (encoded_bytes == 0) { | 299 if (encoded_bytes == 0) { |
| 300 *audio_type = DetermineAudioType(inst, encoded_bytes); | 300 *audio_type = DetermineAudioType(inst, encoded_bytes); |
| 301 decoded_samples = WebRtcOpus_DecodePlc(inst, decoded, 1); | 301 decoded_samples = WebRtcOpus_DecodePlc(inst, decoded, 1); |
| 302 } else { | 302 } else { |
| 303 decoded_samples = DecodeNative(inst, | 303 decoded_samples = DecodeNative(inst, |
| 304 encoded, | 304 encoded, |
| 305 encoded_bytes, | 305 encoded_bytes, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 333 decoded_samples = DecodeNative(inst, NULL, 0, plc_samples, | 333 decoded_samples = DecodeNative(inst, NULL, 0, plc_samples, |
| 334 decoded, &audio_type, 0); | 334 decoded, &audio_type, 0); |
| 335 if (decoded_samples < 0) { | 335 if (decoded_samples < 0) { |
| 336 return -1; | 336 return -1; |
| 337 } | 337 } |
| 338 | 338 |
| 339 return decoded_samples; | 339 return decoded_samples; |
| 340 } | 340 } |
| 341 | 341 |
| 342 int WebRtcOpus_DecodeFec(OpusDecInst* inst, const uint8_t* encoded, | 342 int WebRtcOpus_DecodeFec(OpusDecInst* inst, const uint8_t* encoded, |
| 343 int16_t encoded_bytes, int16_t* decoded, | 343 size_t encoded_bytes, int16_t* decoded, |
| 344 int16_t* audio_type) { | 344 int16_t* audio_type) { |
| 345 int decoded_samples; | 345 int decoded_samples; |
| 346 int fec_samples; | 346 int fec_samples; |
| 347 | 347 |
| 348 if (WebRtcOpus_PacketHasFec(encoded, encoded_bytes) != 1) { | 348 if (WebRtcOpus_PacketHasFec(encoded, encoded_bytes) != 1) { |
| 349 return 0; | 349 return 0; |
| 350 } | 350 } |
| 351 | 351 |
| 352 fec_samples = opus_packet_get_samples_per_frame(encoded, 48000); | 352 fec_samples = opus_packet_get_samples_per_frame(encoded, 48000); |
| 353 | 353 |
| 354 decoded_samples = DecodeNative(inst, encoded, encoded_bytes, | 354 decoded_samples = DecodeNative(inst, encoded, encoded_bytes, |
| 355 fec_samples, decoded, audio_type, 1); | 355 fec_samples, decoded, audio_type, 1); |
| 356 if (decoded_samples < 0) { | 356 if (decoded_samples < 0) { |
| 357 return -1; | 357 return -1; |
| 358 } | 358 } |
| 359 | 359 |
| 360 return decoded_samples; | 360 return decoded_samples; |
| 361 } | 361 } |
| 362 | 362 |
| 363 int WebRtcOpus_DurationEst(OpusDecInst* inst, | 363 int WebRtcOpus_DurationEst(OpusDecInst* inst, |
| 364 const uint8_t* payload, | 364 const uint8_t* payload, |
| 365 int payload_length_bytes) { | 365 size_t payload_length_bytes) { |
| 366 int frames, samples; | 366 int frames, samples; |
| 367 frames = opus_packet_get_nb_frames(payload, payload_length_bytes); | 367 frames = opus_packet_get_nb_frames(payload, (opus_int32)payload_length_bytes); |
| 368 if (frames < 0) { | 368 if (frames < 0) { |
| 369 /* Invalid payload data. */ | 369 /* Invalid payload data. */ |
| 370 return 0; | 370 return 0; |
| 371 } | 371 } |
| 372 samples = frames * opus_packet_get_samples_per_frame(payload, 48000); | 372 samples = frames * opus_packet_get_samples_per_frame(payload, 48000); |
| 373 if (samples < 120 || samples > 5760) { | 373 if (samples < 120 || samples > 5760) { |
| 374 /* Invalid payload duration. */ | 374 /* Invalid payload duration. */ |
| 375 return 0; | 375 return 0; |
| 376 } | 376 } |
| 377 return samples; | 377 return samples; |
| 378 } | 378 } |
| 379 | 379 |
| 380 int WebRtcOpus_FecDurationEst(const uint8_t* payload, | 380 int WebRtcOpus_FecDurationEst(const uint8_t* payload, |
| 381 int payload_length_bytes) { | 381 size_t payload_length_bytes) { |
| 382 int samples; | 382 int samples; |
| 383 if (WebRtcOpus_PacketHasFec(payload, payload_length_bytes) != 1) { | 383 if (WebRtcOpus_PacketHasFec(payload, payload_length_bytes) != 1) { |
| 384 return 0; | 384 return 0; |
| 385 } | 385 } |
| 386 | 386 |
| 387 samples = opus_packet_get_samples_per_frame(payload, 48000); | 387 samples = opus_packet_get_samples_per_frame(payload, 48000); |
| 388 if (samples < 480 || samples > 5760) { | 388 if (samples < 480 || samples > 5760) { |
| 389 /* Invalid payload duration. */ | 389 /* Invalid payload duration. */ |
| 390 return 0; | 390 return 0; |
| 391 } | 391 } |
| 392 return samples; | 392 return samples; |
| 393 } | 393 } |
| 394 | 394 |
| 395 int WebRtcOpus_PacketHasFec(const uint8_t* payload, | 395 int WebRtcOpus_PacketHasFec(const uint8_t* payload, |
| 396 int payload_length_bytes) { | 396 size_t payload_length_bytes) { |
| 397 int frames, channels, payload_length_ms; | 397 int frames, channels, payload_length_ms; |
| 398 int n; | 398 int n; |
| 399 opus_int16 frame_sizes[48]; | 399 opus_int16 frame_sizes[48]; |
| 400 const unsigned char *frame_data[48]; | 400 const unsigned char *frame_data[48]; |
| 401 | 401 |
| 402 if (payload == NULL || payload_length_bytes <= 0) | 402 if (payload == NULL || payload_length_bytes == 0) |
| 403 return 0; | 403 return 0; |
| 404 | 404 |
| 405 /* In CELT_ONLY mode, packets should not have FEC. */ | 405 /* In CELT_ONLY mode, packets should not have FEC. */ |
| 406 if (payload[0] & 0x80) | 406 if (payload[0] & 0x80) |
| 407 return 0; | 407 return 0; |
| 408 | 408 |
| 409 payload_length_ms = opus_packet_get_samples_per_frame(payload, 48000) / 48; | 409 payload_length_ms = opus_packet_get_samples_per_frame(payload, 48000) / 48; |
| 410 if (10 > payload_length_ms) | 410 if (10 > payload_length_ms) |
| 411 payload_length_ms = 10; | 411 payload_length_ms = 10; |
| 412 | 412 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 425 case 60: { | 425 case 60: { |
| 426 frames = 3; | 426 frames = 3; |
| 427 break; | 427 break; |
| 428 } | 428 } |
| 429 default: { | 429 default: { |
| 430 return 0; // It is actually even an invalid packet. | 430 return 0; // It is actually even an invalid packet. |
| 431 } | 431 } |
| 432 } | 432 } |
| 433 | 433 |
| 434 /* The following is to parse the LBRR flags. */ | 434 /* The following is to parse the LBRR flags. */ |
| 435 if (opus_packet_parse(payload, payload_length_bytes, NULL, frame_data, | 435 if (opus_packet_parse(payload, (opus_int32)payload_length_bytes, NULL, |
| 436 frame_sizes, NULL) < 0) { | 436 frame_data, frame_sizes, NULL) < 0) { |
| 437 return 0; | 437 return 0; |
| 438 } | 438 } |
| 439 | 439 |
| 440 if (frame_sizes[0] <= 1) { | 440 if (frame_sizes[0] <= 1) { |
| 441 return 0; | 441 return 0; |
| 442 } | 442 } |
| 443 | 443 |
| 444 for (n = 0; n < channels; n++) { | 444 for (n = 0; n < channels; n++) { |
| 445 if (frame_data[0][0] & (0x80 >> ((n + 1) * (frames + 1) - 1))) | 445 if (frame_data[0][0] & (0x80 >> ((n + 1) * (frames + 1) - 1))) |
| 446 return 1; | 446 return 1; |
| 447 } | 447 } |
| 448 | 448 |
| 449 return 0; | 449 return 0; |
| 450 } | 450 } |
| OLD | NEW |