virtual bool Transcode(const void * fromPtr, unsigned & fromLen, void * toPtr, unsigned & toLen, unsigned & flags) { int samples; const unsigned char * packet; if (fromLen == 0) { packet = NULL; // As per opus_decode() API opus_decoder_ctl(m_decoder, OPUS_GET_LAST_PACKET_DURATION(&samples)); } else { packet = (const unsigned char *)fromPtr; samples = opus_decoder_get_nb_samples(m_decoder, packet, fromLen); if (samples < 0) { PTRACE(1, MY_CODEC_LOG, "Decoding error " << samples << ' ' << opus_strerror(samples)); return false; } } if ((unsigned)samples*m_channels*2U > toLen) { PTRACE(1, MY_CODEC_LOG, "Provided sample buffer too small, " << toLen << " bytes"); return false; } int result = opus_decode(m_decoder, packet, fromLen, (opus_int16 *)toPtr, samples, m_useInBandFEC); if (result < 0) { PTRACE(1, MY_CODEC_LOG, "Decoder error " << result << ' ' << opus_strerror(result)); return false; } toLen = result*m_channels*2; return true; }
static int init_audio_encoder(CSSession *cs) { int rc = OPUS_OK; cs->audio_encoder = opus_encoder_create(cs->audio_encoder_sample_rate, cs->audio_encoder_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_encoder_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; } return 0; }
/** * @brief Receive decoded audio frame. * * @param av Handler. * @param frame_size The size of dest in frames/samples (one frame/sample is 16 bits or 2 bytes * and corresponds to one sample of audio.) * @param dest Destination of the raw audio (16 bit signed pcm with AUDIO_CHANNELS channels). * Make sure it has enough space for frame_size frames/samples. * @return int * @retval >=0 Size of received data in frames/samples. * @retval ToxAvError On error. */ inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, int16_t *dest ) { if ( !dest ) return ErrorInternal; if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } CallSpecific *call = &av->calls[call_index]; uint8_t packet [RTP_PAYLOAD_SIZE]; int recved_size = toxav_recv_rtp_payload(av, call_index, TypeAudio, packet); if ( recved_size == ErrorAudioPacketLost ) { int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); if ( dec_size < 0 ) { LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); return ErrorInternal; } else return dec_size; } else if ( recved_size ) { int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); if ( dec_size < 0 ) { LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); return ErrorInternal; } else return dec_size; } else { return 0; /* Nothing received */ } }
virtual bool Transcode(const void * fromPtr, unsigned & fromLen, void * toPtr, unsigned & toLen, unsigned & flags) { int samples = opus_decoder_get_nb_samples(m_decoder, (const unsigned char *)fromPtr, fromLen); if (samples < 0) { PTRACE(1, MY_CODEC_LOG, "Decoding error " << samples << ' ' << opus_strerror(samples)); return false; } if (samples*m_channels*2 > (int)toLen) { PTRACE(1, MY_CODEC_LOG, "Provided sample buffer too small, " << toLen << " bytes"); return false; } int result = opus_decode(m_decoder, (const unsigned char *)fromPtr, fromLen, (opus_int16 *)toPtr, samples, 0); if (result < 0) { PTRACE(1, MY_CODEC_LOG, "Decoder error " << result << ' ' << opus_strerror(result)); return false; } toLen = result*m_channels*2; return true; }
static void apply_max_bitrate(OpusEncData *d) { ms_message("Setting opus codec bitrate to [%i] from network bitrate [%i] with ptime [%i]", d->bitrate, d->max_network_bitrate, d->ptime); /* give the bitrate to the encoder if exists*/ if (d->state) { opus_int32 maxBandwidth=0; /*tell the target bitrate, opus will choose internally the bandwidth to use*/ int error = opus_encoder_ctl(d->state, OPUS_SET_BITRATE(d->bitrate)); if (error != OPUS_OK) { ms_error("could not set bit rate to opus encoder: %s", opus_strerror(error)); } /* implement maxplaybackrate parameter, which is constraint on top of bitrate */ if (d->maxplaybackrate <= 8000) { maxBandwidth = OPUS_BANDWIDTH_NARROWBAND; } else if (d->maxplaybackrate <= 12000) { maxBandwidth = OPUS_BANDWIDTH_MEDIUMBAND; } else if (d->maxplaybackrate <= 16000) { maxBandwidth = OPUS_BANDWIDTH_WIDEBAND; } else if (d->maxplaybackrate <= 24000) { maxBandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; } else { maxBandwidth = OPUS_BANDWIDTH_FULLBAND; } if (maxBandwidth!=0){ error = opus_encoder_ctl(d->state, OPUS_SET_MAX_BANDWIDTH(maxBandwidth)); if (error != OPUS_OK) { ms_error("could not set max bandwidth to opus encoder: %s", opus_strerror(error)); } } } }
OpusEncoder *create_audio_encoder(Logger *log, int32_t bit_rate, int32_t sampling_rate, int32_t channel_count) { int status = OPUS_OK; OpusEncoder *rc = opus_encoder_create(sampling_rate, channel_count, OPUS_APPLICATION_VOIP, &status); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while starting audio encoder: %s", opus_strerror(status)); return NULL; } status = opus_encoder_ctl(rc, OPUS_SET_BITRATE(bit_rate)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); goto FAILURE; } /* Enable in-band forward error correction in codec */ status = opus_encoder_ctl(rc, OPUS_SET_INBAND_FEC(1)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); goto FAILURE; } /* Make codec resistant to up to 10% packet loss * NOTE This could also be adjusted on the fly, rather than hard-coded, * with feedback from the receiving client. */ status = opus_encoder_ctl(rc, OPUS_SET_PACKET_LOSS_PERC(10)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); goto FAILURE; } /* Set algorithm to the highest complexity, maximizing compression */ status = opus_encoder_ctl(rc, OPUS_SET_COMPLEXITY(10)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); goto FAILURE; } return rc; FAILURE: opus_encoder_destroy(rc); return NULL; }
static void apply_max_bitrate(OpusEncData *d) { ms_message("Setting opus codec bitrate to [%i] from network bitrate [%i] with ptime [%i]", d->bitrate, d->max_network_bitrate, d->ptime); /* give the bitrate to the encoder if exists*/ if (d->state) { opus_int32 maxBandwidth; int error = opus_encoder_ctl(d->state, OPUS_SET_BITRATE(d->bitrate)); if (error != OPUS_OK) { ms_error("could not set bit rate to opus encoder: %s", opus_strerror(error)); } /* set output sampling rate according to bitrate and RFC section 3.1.1 */ if (d->bitrate<12000) { maxBandwidth = OPUS_BANDWIDTH_NARROWBAND; } else if (d->bitrate<20000) { maxBandwidth = OPUS_BANDWIDTH_WIDEBAND; } else if (d->bitrate<40000) { maxBandwidth = OPUS_BANDWIDTH_FULLBAND; } else if (d->bitrate<64000) { maxBandwidth = OPUS_BANDWIDTH_FULLBAND; } else { maxBandwidth = OPUS_BANDWIDTH_FULLBAND; } /* check if selected maxBandwidth is compatible with the maxplaybackrate parameter */ if (d->maxplaybackrate < 12000) { maxBandwidth = OPUS_BANDWIDTH_NARROWBAND; } else if (d->maxplaybackrate < 16000) { if (maxBandwidth != OPUS_BANDWIDTH_NARROWBAND) { maxBandwidth = OPUS_BANDWIDTH_MEDIUMBAND; } } else if (d->maxplaybackrate < 24000) { if (maxBandwidth != OPUS_BANDWIDTH_NARROWBAND) { maxBandwidth = OPUS_BANDWIDTH_WIDEBAND; } } else if (d->maxplaybackrate < 48000) { if (maxBandwidth == OPUS_BANDWIDTH_FULLBAND) { maxBandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; } } error = opus_encoder_ctl(d->state, OPUS_SET_MAX_BANDWIDTH(maxBandwidth)); if (error != OPUS_OK) { ms_error("could not set max bandwidth to opus encoder: %s", opus_strerror(error)); } } }
static int libopus_decode(AVCodecContext *avc, void *frame, int *got_frame_ptr, AVPacket *pkt) { struct libopus_context *opus = avc->priv_data; int ret, nb_samples; opus->frame.nb_samples = MAX_FRAME_SIZE; ret = avc->get_buffer(avc, &opus->frame); if (ret < 0) { av_log(avc, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (avc->sample_fmt == AV_SAMPLE_FMT_S16) nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size, (opus_int16 *)opus->frame.data[0], opus->frame.nb_samples, 0); else nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, (float *)opus->frame.data[0], opus->frame.nb_samples, 0); if (nb_samples < 0) { av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n", opus_strerror(nb_samples)); return ff_opus_error_to_averror(nb_samples); } opus->frame.nb_samples = nb_samples; *(AVFrame *)frame = opus->frame; *got_frame_ptr = 1; return pkt->size; }
bool reconfigure_audio_encoder(Logger *log, OpusEncoder **e, int32_t new_br, int32_t new_sr, uint8_t new_ch, int32_t *old_br, int32_t *old_sr, int32_t *old_ch) { /* Values are checked in toxav.c */ if (*old_sr != new_sr || *old_ch != new_ch) { OpusEncoder *new_encoder = create_audio_encoder(log, new_br, new_sr, new_ch); if (new_encoder == NULL) { return false; } opus_encoder_destroy(*e); *e = new_encoder; } else if (*old_br == new_br) { return true; /* Nothing changed */ } int status = opus_encoder_ctl(*e, OPUS_SET_BITRATE(new_br)); if (status != OPUS_OK) { LOGGER_ERROR(log, "Error while setting encoder ctl: %s", opus_strerror(status)); return false; } *old_br = new_br; *old_sr = new_sr; *old_ch = new_ch; LOGGER_DEBUG(log, "Reconfigured audio encoder br: %d sr: %d cc:%d", new_br, new_sr, new_ch); return true; }
static int opustolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f) { struct opus_coder_pvt *opvt = pvt->pvt; int samples = 0; /* Decode */ ast_debug(3, "[Decoder #%d (%d)] %d samples, %d bytes\n", opvt->id, opvt->sampling_rate, f->samples, f->datalen); if ((samples = opus_decode(opvt->opus, f->data.ptr, f->datalen, pvt->outbuf.i16, BUFFER_SAMPLES, opvt->fec)) < 0) { ast_log(LOG_ERROR, "Error decoding the Opus frame: %s\n", opus_strerror(samples)); return -1; } pvt->samples += samples; pvt->datalen += samples * 2; ast_debug(3, "[Decoder #%d (%d)] >> Got %d samples, %d bytes\n", opvt->id, opvt->sampling_rate, pvt->samples, pvt->datalen); return 0; }
/** * @brief Encode audio frame * * @param av Handler * @param dest dest * @param dest_max Max dest size * @param frame The frame * @param frame_size The frame size * @return int * @retval ToxAvError On error. * @retval >0 On success */ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, const int16_t *frame, int frame_size) { if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) { LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } CallSpecific *call = &av->calls[call_index]; pthread_mutex_lock(&call->mutex); if (!call->call_active) { pthread_mutex_unlock(&call->mutex); LOGGER_WARNING("Action on inactive call: %d", call_index); return ErrorNoCall; } int32_t rc = opus_encode(call->cs->audio_encoder, frame, frame_size, dest, dest_max); pthread_mutex_unlock(&call->mutex); if (rc < 0) { LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); return ErrorInternal; } return rc; }
int krad_opus_decoder_write (krad_opus_t *krad_opus, uint8_t *buffer, int length) { int i; int frames_decoded; frames_decoded = 0; krad_opus->opus_decoder_error = opus_multistream_decode_float (krad_opus->decoder, buffer, length, krad_opus->interleaved_samples, 2880 * 2, 0); if (krad_opus->opus_decoder_error < 0) { printke ("Krad Opus decoder error: %s\n", opus_strerror (krad_opus->opus_decoder_error)); } else { frames_decoded = krad_opus->opus_decoder_error; } for (i = 0; i < frames_decoded; i++) { krad_opus->samples[0][i] = krad_opus->interleaved_samples[i * 2 + 0]; krad_opus->samples[1][i] = krad_opus->interleaved_samples[i * 2 + 1]; } krad_ringbuffer_write (krad_opus->ringbuf[0], (char *)krad_opus->samples[0], (frames_decoded * 4) ); krad_ringbuffer_write (krad_opus->ringbuf[1], (char *)krad_opus->samples[1], (frames_decoded * 4) ); return 0; }
static int opus_decoder_construct(struct ast_trans_pvt *pvt, int sampling_rate) { struct opus_coder_pvt *opvt = pvt->pvt; int error = 0; if (!valid_sampling_rate(sampling_rate)) { return -1; } opvt->sampling_rate = sampling_rate; opvt->multiplier = 48000/sampling_rate; opvt->fec = USE_FEC; /* FIXME: should be triggered by chan_sip */ opvt->opus = opus_decoder_create(sampling_rate, 1, &error); if (error != OPUS_OK) { ast_log(LOG_ERROR, "Error creating the Opus decoder: %s\n", opus_strerror(error)); return -1; } opvt->id = ast_atomic_fetchadd_int(&usage.decoder_id, 1) + 1; ast_atomic_fetchadd_int(&usage.decoders, +1); ast_debug(3, "Created decoder #%d (opus -> %d)\n", opvt->id, sampling_rate); return 0; }
static void ms_opus_enc_preprocess(MSFilter *f) { int error; OpusEncData *d = (OpusEncData *)f->data; /* create the encoder */ d->state = opus_encoder_create(d->samplerate, d->channels, d->application, &error); if (error != OPUS_OK) { ms_error("Opus encoder creation failed: %s", opus_strerror(error)); return; } /* set complexity to 0 for single processor arm devices */ #if defined(__arm__) || defined(_M_ARM) if (ms_factory_get_cpu_count(f->factory)==1){ opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(0)); }else{ opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(5)); } #endif error = opus_encoder_ctl(d->state, OPUS_SET_PACKET_LOSS_PERC(10)); if (error != OPUS_OK) { ms_error("Could not set default loss percentage to opus encoder: %s", opus_strerror(error)); } /* set the encoder parameters: VBR, IN_BAND_FEC, DTX and bitrate settings */ ms_opus_enc_set_vbr(f); ms_opus_enc_set_inbandfec(f); ms_opus_enc_set_dtx(f); /* if decoder prefers mono signal, force encoder to output mono signal */ if (d->stereo == 0) { error = opus_encoder_ctl(d->state, OPUS_SET_FORCE_CHANNELS(1)); if (error != OPUS_OK) { ms_error("could not force mono channel to opus encoder: %s", opus_strerror(error)); } if (d->channels == 2) ms_message("Opus encoder configured to encode mono despite it is feed with stereo."); }else if (d->channels == 2){ ms_message("Opus encoder configured to encode stereo."); } ms_filter_lock(f); // set bitrate wasn't call, compute it with the default network bitrate (36000) if (d->bitrate==-1) { compute_max_bitrate(d, 0); } apply_max_bitrate(d); ms_filter_unlock(f); }
virtual bool Construct() { int error; if ((m_encoder = opus_encoder_create(m_sampleRate, m_channels, OPUS_APPLICATION_VOIP, &error)) != NULL) return true; PTRACE(1, MY_CODEC_LOG, "Encoder create error " << error << ' ' << opus_strerror(error)); return false; }
virtual bool Construct() { int error; if ((m_decoder = opus_decoder_create(m_sampleRate, m_channels, &error)) != NULL) return true; PTRACE(1, MY_CODEC_LOG, "Decoder create error " << error << ' ' << opus_strerror(error)); return false; }
static void ms_opus_dec_preprocess(MSFilter *f) { int error; OpusDecData *d = (OpusDecData *)f->data; d->state = opus_decoder_create(d->samplerate, d->channels, &error); if (error != OPUS_OK) { ms_error("Opus decoder creation failed: %s", opus_strerror(error)); } /* initialise the concealer context */ d->concealer = ms_concealer_context_new(UINT32_MAX); }
OpusEncoder *tc_opus_create_encoder(int sample_rate, int channels, int bitrate) { int err; OpusEncoder *encoder = opus_encoder_create(sample_rate, channels, OPUS_APPLICATION_AUDIO, &err); if (err<0){ pa_log_error("failed to create an encoder: %s", opus_strerror(err)); return NULL; } err = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(bitrate)); if (err<0) { pa_log_error("failed to set bitrate: %s", opus_strerror(err)); return NULL; } return encoder; }
static void ms_opus_enc_preprocess(MSFilter *f) { int error; OpusEncData *d = (OpusEncData *)f->data; /* create the encoder */ d->state = opus_encoder_create(d->samplerate, d->channels, d->application, &error); if (error != OPUS_OK) { ms_error("Opus encoder creation failed: %s", opus_strerror(error)); return; } /* set complexity to 0 for arm devices */ #ifdef __arm__ opus_encoder_ctl(d->state, OPUS_SET_COMPLEXITY(0)); #endif error = opus_encoder_ctl(d->state, OPUS_SET_PACKET_LOSS_PERC(10)); if (error != OPUS_OK) { ms_error("Could not set default loss percentage to opus encoder: %s", opus_strerror(error)); } /* set the encoder parameters: VBR, IN_BAND_FEC, DTX and bitrate settings */ ms_opus_enc_set_vbr(f); ms_opus_enc_set_inbandfec(f); ms_opus_enc_set_dtx(f); /* if decoder prefers mono signal, force encoder to output mono signal */ if (d->stereo == 0) { error = opus_encoder_ctl(d->state, OPUS_SET_FORCE_CHANNELS(1)); if (error != OPUS_OK) { ms_error("could not force mono channel to opus encoder: %s", opus_strerror(error)); } } ms_filter_lock(f); if (d->ptime==-1) { // set ptime wasn't call, set default:20ms d->ptime = 20; } if (d->bitrate==-1) { // set bitrate wasn't call, compute it with the default network bitrate (36000) compute_max_bitrate(d, 0); } apply_max_bitrate(d); ms_filter_unlock(f); }
AM_UINT CAudioCodecOpus::encode(AM_U8 *input, AM_UINT inDataSize, AM_U8 *output, AM_UINT *outDataSize) { *outDataSize = 0; if (AM_LIKELY(0 == (inDataSize % mEncFrameBytes))) { bool isOk = true; AM_U8 *out = mEncodeBuf; memset(out, 0, sizeof(mEncodeBuf)); mRepacketizer = opus_repacketizer_init(mRepacketizer); for (AM_UINT i = 0; i < (inDataSize / mEncFrameBytes); ++ i) { const opus_int16* pcm = (opus_int16*)(input + i * mEncFrameBytes); int ret = opus_encode(mEncoder, pcm, mEncFrameSize, out, 4096); if (AM_LIKELY(ret > 0)) { int retval = opus_repacketizer_cat(mRepacketizer, out, ret); if (AM_UNLIKELY(retval != OPUS_OK)) { ERROR("Opus repacketizer error: %s", opus_strerror(retval)); isOk = false; break; } out += ret; } else { ERROR("Opus encode error: %s", opus_strerror(ret)); isOk = false; break; } } if (AM_LIKELY(isOk)) { int ret = opus_repacketizer_out(mRepacketizer, output, 4096); if (AM_LIKELY(ret > 0)) { *outDataSize = ret; } else { ERROR("Opus repacketizer error: %s", opus_strerror(ret)); } } } else { ERROR("Invalid input data length: %u, must be n times of %u", inDataSize, mEncFrameBytes); } return *outDataSize; }
/** * @brief Encode audio frame * * @param av Handler * @param dest dest * @param dest_max Max dest size * @param frame The frame * @param frame_size The frame size * @return int * @retval ToxAvError On error. * @retval >0 On success */ inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, const int16_t *frame, int frame_size) { int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); if (rc < 0) { fprintf(stderr, "Failed to encode payload: %s\n", opus_strerror(rc)); return ErrorInternal; } return rc; }
static int init_audio_decoder(CSSession *cs) { int rc; cs->audio_decoder = opus_decoder_create(cs->audio_decoder_sample_rate, cs->audio_decoder_channels, &rc ); if ( rc != OPUS_OK ) { LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(rc)); return -1; } return 0; }
OpusDecoder *tc_opus_create_decoder(int sample_rate, int channels) { int err; OpusDecoder * decoder = opus_decoder_create(sample_rate, channels, &err); if (err<0) { pa_log_error("failed to create decoder: %s", opus_strerror(err)); return NULL; } return decoder; }
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; } return 0; }
int opus_enc_init(opus_enc *opus) { int err; err = 0; opus->header = (OpusHeader *)calloc(1, sizeof(OpusHeader)); opus->header_data = (unsigned char *)calloc (1, 1024); opus->tags = (unsigned char *)calloc (1, 1024); opus->buffer = (unsigned char *)calloc (1, 4 * 4096); srand(time(NULL)); ogg_stream_init(&opus->os, rand()); opus->header->gain = 0; opus->header->channels = opus->channel; if ((opus->bitrate < 8000) || (opus->bitrate > 320000)) { opus->bitrate = DEFAULT_OPUS_BITRATE; } opus->header->input_sample_rate = 48000; opus->encoder = opus_encoder_create (opus->header->input_sample_rate, opus->channel, OPUS_APPLICATION_AUDIO, &err); opus_encoder_ctl (opus->encoder, OPUS_SET_BITRATE(opus->bitrate)); if (opus->encoder == NULL) { printf("Opus Encoder creation error: %s\n", opus_strerror (err)); return 1; } opus->last_bitrate = opus->bitrate; opus_encoder_ctl (opus->encoder, OPUS_GET_LOOKAHEAD (&opus->header->preskip)); opus->header_size = opus_header_to_packet (opus->header, opus->header_data, 100); opus->tags_size = 8 + 4 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER=") + strlen (VERSION); memcpy (opus->tags, "OpusTags", 8); opus->tags[8] = strlen (opus_get_version_string ()); memcpy (opus->tags + 12, opus_get_version_string (), strlen (opus_get_version_string ())); opus->tags[12 + strlen (opus_get_version_string ())] = 1; opus->tags[12 + strlen (opus_get_version_string ()) + 4] = strlen ("ENCODER=") + strlen (VERSION); memcpy (opus->tags + 12 + strlen (opus_get_version_string ()) + 4 + 4, "ENCODER=", strlen ("ENCODER=")); memcpy (opus->tags + 12 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER="), VERSION, strlen (VERSION)); //printf("Opus Encoder Created\n"); return 0; }
static int ms_opus_enc_set_dtx(MSFilter *f) { OpusEncData *d = (OpusEncData *)f->data; int error; if (d->state) { error = opus_encoder_ctl(d->state, OPUS_SET_DTX(d->usedtx)); if (error != OPUS_OK) { ms_error("could not set use DTX to opus encoder: %s", opus_strerror(error)); } } return 0; }
static int ms_opus_enc_set_inbandfec(MSFilter *f) { OpusEncData *d = (OpusEncData *)f->data; int error; if (d->state) { error = opus_encoder_ctl(d->state, OPUS_SET_INBAND_FEC(d->useinbandfec)); if (error != OPUS_OK) { ms_error("could not set inband FEC to opus encoder: %s", opus_strerror(error)); } } return 0; }
/** * @brief Encode audio frame * * @param av Handler * @param dest dest * @param dest_max Max dest size * @param frame The frame * @param frame_size The frame size * @return int * @retval ToxAvError On error. * @retval >0 On success */ inline__ int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, const int16_t *frame, int frame_size) { if (cii(call_index, av->msi_session)) return ErrorNoCall; int32_t rc = opus_encode(av->calls[call_index].cs->audio_encoder, frame, frame_size, dest, dest_max); if (rc < 0) { LOGGER_ERROR("Failed to encode payload: %s\n", opus_strerror(rc)); return ErrorInternal; } return rc; }
static int recreate_encoder(Group_AV *group_av) { if (group_av->audio_encoder) { opus_encoder_destroy(group_av->audio_encoder); group_av->audio_encoder = NULL; } int rc = OPUS_OK; group_av->audio_encoder = opus_encoder_create(group_av->audio_sample_rate, group_av->audio_channels, OPUS_APPLICATION_AUDIO, &rc); if (rc != OPUS_OK) { LOGGER_ERROR("Error while starting audio encoder: %s", opus_strerror(rc)); group_av->audio_encoder = NULL; return -1; } rc = opus_encoder_ctl(group_av->audio_encoder, OPUS_SET_BITRATE(group_av->audio_bitrate)); if (rc != OPUS_OK) { LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc)); opus_encoder_destroy(group_av->audio_encoder); group_av->audio_encoder = NULL; return -1; } rc = opus_encoder_ctl(group_av->audio_encoder, OPUS_SET_COMPLEXITY(10)); if (rc != OPUS_OK) { LOGGER_ERROR("Error while setting encoder ctl: %s", opus_strerror(rc)); opus_encoder_destroy(group_av->audio_encoder); group_av->audio_encoder = NULL; return -1; } return 0; }
static int libopus_decode(AVCodecContext *avc, void *data, int *got_frame_ptr, AVPacket *pkt) { struct libopus_context *opus = avc->priv_data; AVFrame *frame = data; int ret, nb_samples; frame->nb_samples = MAX_FRAME_SIZE; ret = ff_get_buffer(avc, frame); if (ret < 0) { av_log(avc, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } if (avc->sample_fmt == AV_SAMPLE_FMT_S16) nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size, (opus_int16 *)frame->data[0], frame->nb_samples, 0); else nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size, (float *)frame->data[0], frame->nb_samples, 0); if (nb_samples < 0) { av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n", opus_strerror(nb_samples)); return ff_opus_error_to_averror(nb_samples); } #ifndef OPUS_SET_GAIN { int i = avc->channels * nb_samples; if (avc->sample_fmt == AV_SAMPLE_FMT_FLT) { float *pcm = (float *)frame->data[0]; for (; i > 0; i--, pcm++) *pcm = av_clipf(*pcm * opus->gain.d, -1, 1); } else { int16_t *pcm = (int16_t *)frame->data[0]; for (; i > 0; i--, pcm++) *pcm = av_clip_int16(((int64_t)opus->gain.i * *pcm) >> 16); } } #endif frame->nb_samples = nb_samples; *got_frame_ptr = 1; return pkt->size; }