diff options
author | mannol <eniz_vukovic@hotmail.com> | 2015-04-09 02:43:13 +0200 |
---|---|---|
committer | mannol <eniz_vukovic@hotmail.com> | 2015-04-09 02:43:13 +0200 |
commit | 4fa31d14cf53dd54b182508df31b5524b1f24cb6 (patch) | |
tree | 13b41abf8698f87307be2e6e8f7b78ce033af659 /toxav/codec.c | |
parent | 9c003c9dd215d5f6bb2c1a0fbdc2c0f7fd9def7c (diff) |
Make it possible to decode mono audio with stereo decoder
Diffstat (limited to 'toxav/codec.c')
-rw-r--r-- | toxav/codec.c | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/toxav/codec.c b/toxav/codec.c index cd26d1e3..be69ee70 100644 --- a/toxav/codec.c +++ b/toxav/codec.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "rtp.h" | 38 | #include "rtp.h" |
39 | #include "codec.h" | 39 | #include "codec.h" |
40 | 40 | ||
41 | #define DEFAULT_JBUF 6 | 41 | #define DEFAULT_JBUF 3 |
42 | 42 | ||
43 | /* Good quality encode. */ | 43 | /* Good quality encode. */ |
44 | #define MAX_DECODE_TIME_US 0 | 44 | #define MAX_DECODE_TIME_US 0 |
@@ -342,39 +342,59 @@ void cs_do(CSession *cs) | |||
342 | (cs->last_packet_sampling_rate * cs->last_packet_frame_duration / 1000) * | 342 | (cs->last_packet_sampling_rate * cs->last_packet_frame_duration / 1000) * |
343 | cs->last_packet_channel_count, 1); | 343 | cs->last_packet_channel_count, 1); |
344 | } else { | 344 | } else { |
345 | /* Get values from packet and decode. | 345 | /* Get values from packet and decode. */ |
346 | * It also checks for validity of an opus packet | 346 | /* NOTE: This didn't work very well |
347 | */ | ||
348 | rc = convert_bw_to_sampling_rate(opus_packet_get_bandwidth(msg->data)); | 347 | rc = convert_bw_to_sampling_rate(opus_packet_get_bandwidth(msg->data)); |
349 | if (rc != -1) { | 348 | if (rc != -1) { |
350 | cs->last_packet_sampling_rate = rc; | 349 | cs->last_packet_sampling_rate = rc; |
351 | cs->last_packet_channel_count = opus_packet_get_nb_channels(msg->data); | ||
352 | |||
353 | cs->last_packet_frame_duration = | ||
354 | ( opus_packet_get_samples_per_frame(msg->data, cs->last_packet_sampling_rate) * 1000 ) | ||
355 | / cs->last_packet_sampling_rate; | ||
356 | |||
357 | /* TODO FIXME WARNING calculate properly according to propper channel count */ | ||
358 | cs->last_packet_frame_duration /= cs->last_packet_channel_count; | ||
359 | } else { | 350 | } else { |
360 | LOGGER_WARNING("Failed to load packet values!"); | 351 | LOGGER_WARNING("Failed to load packet values!"); |
361 | rtp_free_msg(NULL, msg); | 352 | rtp_free_msg(NULL, msg); |
362 | continue; | 353 | continue; |
363 | } | 354 | }*/ |
355 | |||
364 | 356 | ||
365 | rc = opus_decode(cs->audio_decoder, msg->data, msg->length, tmp, 5760, 0); | 357 | /* Pick up sampling rate from packet */ |
358 | memcpy(&cs->last_packet_sampling_rate, msg->data, 4); | ||
359 | cs->last_packet_sampling_rate = ntohl(cs->last_packet_sampling_rate); | ||
360 | |||
361 | cs->last_packet_channel_count = opus_packet_get_nb_channels(msg->data + 4); | ||
362 | rc = opus_decode(cs->audio_decoder, msg->data + 4, msg->length - 4, tmp, 5760, 0); | ||
366 | rtp_free_msg(NULL, msg); | 363 | rtp_free_msg(NULL, msg); |
367 | } | 364 | } |
368 | 365 | ||
369 | if (rc < 0) { | 366 | if (rc < 0) { |
370 | LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); | 367 | LOGGER_WARNING("Decoding error: %s", opus_strerror(rc)); |
371 | } else if (cs->acb.first) { | 368 | } else if (cs->acb.first) { |
372 | /* Play */ | ||
373 | LOGGER_DEBUG("Playing audio frame size: %d; channels: %d; srate: %d; duration %d", rc, | ||
374 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->last_packet_frame_duration); | ||
375 | 369 | ||
376 | cs->acb.first(cs->av, cs->friend_id, tmp, rc, | 370 | /* Extract channels */ |
377 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); | 371 | int16_t left[rc/2]; |
372 | int16_t right[rc/2]; | ||
373 | int i = 0; | ||
374 | for (; i < rc/2; i ++) { | ||
375 | left[i] = tmp[i * 2]; | ||
376 | right[i] = tmp[(i * 2) + 1]; | ||
377 | } | ||
378 | |||
379 | if (memcmp(left, right, sizeof(int16_t)) == 0) { | ||
380 | cs->last_packet_channel_count = 1; | ||
381 | cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count; | ||
382 | |||
383 | LOGGER_DEBUG("Playing mono audio frame size: %d; srate: %d; duration %d", rc, | ||
384 | cs->last_packet_sampling_rate, cs->last_packet_frame_duration); | ||
385 | |||
386 | cs->acb.first(cs->av, cs->friend_id, right, rc / 2, | ||
387 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); | ||
388 | } else { | ||
389 | cs->last_packet_channel_count = 2; | ||
390 | cs->last_packet_frame_duration = (rc * 1000) / cs->last_packet_sampling_rate * cs->last_packet_channel_count; | ||
391 | |||
392 | LOGGER_DEBUG("Playing stereo audio frame size: %d; channels: %d; srate: %d; duration %d", rc, | ||
393 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->last_packet_frame_duration); | ||
394 | |||
395 | cs->acb.first(cs->av, cs->friend_id, tmp, rc, | ||
396 | cs->last_packet_channel_count, cs->last_packet_sampling_rate, cs->acb.second); | ||
397 | } | ||
378 | } | 398 | } |
379 | 399 | ||
380 | LOGGED_LOCK(cs->queue_mutex); | 400 | LOGGED_LOCK(cs->queue_mutex); |
@@ -438,7 +458,7 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size) | |||
438 | */ | 458 | */ |
439 | 459 | ||
440 | int status; | 460 | int status; |
441 | cs->audio_decoder = opus_decoder_create(48000, 1, &status ); /* NOTE: Must be mono */ | 461 | cs->audio_decoder = opus_decoder_create(48000, 2, &status ); /* NOTE: Must be stereo */ |
442 | 462 | ||
443 | if ( status != OPUS_OK ) { | 463 | if ( status != OPUS_OK ) { |
444 | LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(status)); | 464 | LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(status)); |
@@ -482,7 +502,7 @@ CSession *cs_new(uint32_t peer_video_frame_piece_size) | |||
482 | goto FAILURE; | 502 | goto FAILURE; |
483 | 503 | ||
484 | cs->linfts = current_time_monotonic(); | 504 | cs->linfts = current_time_monotonic(); |
485 | cs->lcfd = 10; | 505 | cs->lcfd = 60; |
486 | /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | 506 | /*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ |
487 | 507 | ||
488 | /* Initialize encoders with default values */ | 508 | /* Initialize encoders with default values */ |
@@ -579,6 +599,8 @@ const uint8_t *cs_iterate_split_video_frame(CSession *cs, uint16_t *size) | |||
579 | return cs->split_video_frame; | 599 | return cs->split_video_frame; |
580 | } | 600 | } |
581 | 601 | ||
602 | |||
603 | |||
582 | int cs_reconfigure_video_encoder(CSession* cs, int32_t bitrate, uint16_t width, uint16_t height) | 604 | int cs_reconfigure_video_encoder(CSession* cs, int32_t bitrate, uint16_t width, uint16_t height) |
583 | { | 605 | { |
584 | vpx_codec_enc_cfg_t cfg = *cs->v_encoder[0].config.enc; | 606 | vpx_codec_enc_cfg_t cfg = *cs->v_encoder[0].config.enc; |