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 |