diff options
Diffstat (limited to 'protocols/Tox/toxcore/toxav/codec.c')
-rw-r--r-- | protocols/Tox/toxcore/toxav/codec.c | 357 |
1 files changed, 0 insertions, 357 deletions
diff --git a/protocols/Tox/toxcore/toxav/codec.c b/protocols/Tox/toxcore/toxav/codec.c deleted file mode 100644 index 10dc4f53ff..0000000000 --- a/protocols/Tox/toxcore/toxav/codec.c +++ /dev/null @@ -1,357 +0,0 @@ -/** codec.c - * - * Audio and video codec intitialization, encoding/decoding and playback - * - * Copyright (C) 2013 Tox project All Rights Reserved. - * - * This file is part of Tox. - * - * Tox is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see <http://www.gnu.org/licenses/>. - * - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include "../toxcore/logger.h" - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <assert.h> - -#include "rtp.h" -#include "codec.h" - -JitterBuffer *create_queue(unsigned int capacity) -{ - unsigned int size = 1; - - while (size <= capacity) { - size *= 2; - } - - JitterBuffer *q; - - if ( !(q = calloc(sizeof(JitterBuffer), 1)) ) return NULL; - - if (!(q->queue = calloc(sizeof(RTPMessage *), size))) { - free(q); - return NULL; - } - - q->size = size; - q->capacity = capacity; - return q; -} - -static void clear_queue(JitterBuffer *q) -{ - for (; q->bottom != q->top; ++q->bottom) { - if (q->queue[q->bottom % q->size]) { - rtp_free_msg(NULL, q->queue[q->bottom % q->size]); - q->queue[q->bottom % q->size] = NULL; - } - } -} - -void terminate_queue(JitterBuffer *q) -{ - if (!q) return; - - clear_queue(q); - free(q->queue); - free(q); -} - -void queue(JitterBuffer *q, RTPMessage *pk) -{ - uint16_t sequnum = pk->header->sequnum; - - unsigned int num = sequnum % q->size; - - if ((uint32_t)(sequnum - q->bottom) > q->size) { - clear_queue(q); - q->bottom = sequnum; - q->queue[num] = pk; - q->top = sequnum + 1; - return; - } - - if (q->queue[num]) - return; - - q->queue[num] = pk; - - if ((sequnum - q->bottom) >= (q->top - q->bottom)) - q->top = sequnum + 1; -} - -/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */ -RTPMessage *dequeue(JitterBuffer *q, int *success) -{ - if (q->top == q->bottom) { - *success = 0; - return NULL; - } - - unsigned int num = q->bottom % q->size; - - if (q->queue[num]) { - RTPMessage *ret = q->queue[num]; - q->queue[num] = NULL; - ++q->bottom; - *success = 1; - return ret; - } - - if ((uint32_t)(q->top - q->bottom) > q->capacity) { - ++q->bottom; - *success = 2; - return NULL; - } - - *success = 0; - return NULL; -} - - -int init_video_decoder(CodecState *cs) -{ - int rc = vpx_codec_dec_init_ver(&cs->v_decoder, VIDEO_CODEC_DECODER_INTERFACE, NULL, 0, VPX_DECODER_ABI_VERSION); - - if ( rc != VPX_CODEC_OK) { - LOGGER_ERROR("Init video_decoder failed: %s", vpx_codec_err_to_string(rc)); - return -1; - } - - return 0; -} - -int init_audio_decoder(CodecState *cs, uint32_t audio_channels) -{ - int rc; - cs->audio_decoder = opus_decoder_create(cs->audio_sample_rate, audio_channels, &rc ); - - if ( rc != OPUS_OK ) { - LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(rc)); - return -1; - } - - cs->audio_decoder_channels = audio_channels; - return 0; -} - -int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_t height) -{ - vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc; - - if (cfg.g_w == width && cfg.g_h == height) - return 0; - - if (width * height > cs->max_width * cs->max_height) - return -1; - - LOGGER_DEBUG("New video resolution: %u %u", width, height); - cfg.g_w = width; - cfg.g_h = height; - int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg); - - if ( rc != VPX_CODEC_OK) { - LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc)); - return -1; - } - - return 0; -} - -int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate) -{ - vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc; - - if (cfg.rc_target_bitrate == video_bitrate) - return 0; - - LOGGER_DEBUG("New video bitrate: %u", video_bitrate); - cfg.rc_target_bitrate = video_bitrate; - int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg); - - if ( rc != VPX_CODEC_OK) { - LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc)); - return -1; - } - - return 0; -} - -int init_video_encoder(CodecState *cs, uint16_t max_width, uint16_t max_height, uint32_t video_bitrate) -{ - vpx_codec_enc_cfg_t cfg; - int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); - - if (rc != VPX_CODEC_OK) { - LOGGER_ERROR("Failed to get config: %s", vpx_codec_err_to_string(rc)); - return -1; - } - - cfg.rc_target_bitrate = video_bitrate; - cfg.g_w = max_width; - cfg.g_h = max_height; - cfg.g_pass = VPX_RC_ONE_PASS; - cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS; - cfg.g_lag_in_frames = 0; - cfg.kf_min_dist = 0; - cfg.kf_max_dist = 300; - cfg.kf_mode = VPX_KF_AUTO; - - cs->max_width = max_width; - cs->max_height = max_height; - cs->bitrate = video_bitrate; - - rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION); - - if ( rc != VPX_CODEC_OK) { - LOGGER_ERROR("Failed to initialize encoder: %s", vpx_codec_err_to_string(rc)); - return -1; - } - - rc = vpx_codec_control(&cs->v_encoder, VP8E_SET_CPUUSED, 7); - - if ( rc != VPX_CODEC_OK) { - LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc)); - return -1; - } - - return 0; -} - -int init_audio_encoder(CodecState *cs, uint32_t audio_channels) -{ - int rc = OPUS_OK; - cs->audio_encoder = opus_encoder_create(cs->audio_sample_rate, audio_channels, OPUS_APPLICATION_AUDIO, &rc); - - if ( rc != OPUS_OK ) { - LOGGER_ERROR("Error while starting audio encoder: %s", opus_strerror(rc)); - return -1; - } - - rc = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_BITRATE(cs->audio_bitrate)); - - if ( rc != OPUS_OK ) { - LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc)); - return -1; - } - - rc = opus_encoder_ctl(cs->audio_encoder, OPUS_SET_COMPLEXITY(10)); - - if ( rc != OPUS_OK ) { - LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc)); - return -1; - } - - cs->audio_encoder_channels = audio_channels; - return 0; -} - - -CodecState *codec_init_session ( uint32_t audio_bitrate, - uint16_t audio_frame_duration, - uint32_t audio_sample_rate, - uint32_t encoder_audio_channels, - uint32_t decoder_audio_channels, - uint32_t audio_VAD_tolerance_ms, - uint16_t max_video_width, - uint16_t max_video_height, - uint32_t video_bitrate ) -{ - CodecState *retu = calloc(sizeof(CodecState), 1); - - if (!retu) return NULL; - - retu->audio_bitrate = audio_bitrate; - retu->audio_sample_rate = audio_sample_rate; - - /* Encoders */ - if (!max_video_width || !max_video_height) { /* Disable video */ - /*video_width = 320; - video_height = 240; */ - } else { - retu->capabilities |= ( 0 == init_video_encoder(retu, max_video_width, max_video_height, - video_bitrate) ) ? v_encoding : 0; - retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0; - } - - retu->capabilities |= ( 0 == init_audio_encoder(retu, encoder_audio_channels) ) ? a_encoding : 0; - retu->capabilities |= ( 0 == init_audio_decoder(retu, decoder_audio_channels) ) ? a_decoding : 0; - - if ( retu->capabilities == 0 ) { /* everything failed */ - free (retu); - return NULL; - } - - - retu->EVAD_tolerance = audio_VAD_tolerance_ms > audio_frame_duration ? - audio_VAD_tolerance_ms / audio_frame_duration : audio_frame_duration; - - return retu; -} - -void codec_terminate_session ( CodecState *cs ) -{ - if (!cs) return; - - if ( cs->audio_encoder ) - opus_encoder_destroy(cs->audio_encoder); - - if ( cs->audio_decoder ) - opus_decoder_destroy(cs->audio_decoder); - - if ( cs->capabilities & v_decoding ) - vpx_codec_destroy(&cs->v_decoder); - - if ( cs->capabilities & v_encoding ) - vpx_codec_destroy(&cs->v_encoder); - - LOGGER_DEBUG("Terminated codec state: %p", cs); - free(cs); -} - -static float calculate_sum_sq (int16_t *n, uint16_t k) -{ - float result = 0; - uint16_t i = 0; - - for ( ; i < k; i ++) result += (float) (n[i] * n[i]); - - return result; -} - -int energy_VAD(CodecState *cs, int16_t *PCM, uint16_t frame_size, float energy) -{ - float frame_energy = sqrt(calculate_sum_sq(PCM, frame_size)) / frame_size; - - if ( frame_energy > energy) { - cs->EVAD_tolerance_cr = cs->EVAD_tolerance; /* Reset counter */ - return 1; - } - - if ( cs->EVAD_tolerance_cr ) { - cs->EVAD_tolerance_cr --; - return 1; - } - - return 0; -} |