OggOpusFile::~OggOpusFile() { free(m_outBuf); opus_multistream_encoder_destroy(st); ogg_stream_clear(&os); if(opt_ctls)free(opt_ctls_ctlval); }
static gboolean gst_opus_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info) { GstOpusEnc *enc; enc = GST_OPUS_ENC (benc); g_mutex_lock (enc->property_lock); enc->n_channels = GST_AUDIO_INFO_CHANNELS (info); enc->sample_rate = GST_AUDIO_INFO_RATE (info); gst_opus_enc_setup_channel_mappings (enc, info); GST_DEBUG_OBJECT (benc, "Setup with %d channels, %d Hz", enc->n_channels, enc->sample_rate); /* handle reconfigure */ if (enc->state) { opus_multistream_encoder_destroy (enc->state); enc->state = NULL; } if (!gst_opus_enc_setup (enc)) return FALSE; enc->frame_samples = gst_opus_enc_get_frame_samples (enc); /* feedback to base class */ gst_opus_enc_setup_base_class (enc, benc); g_mutex_unlock (enc->property_lock); return TRUE; }
void Destroy(OpusMSEncoder* Encoder) const { #if USE_UE4_MEM_ALLOC FMemory::Free(Encoder); #else opus_multistream_encoder_destroy(Encoder); #endif }
~FOpusDecoderWrapper() { #if WITH_OPUS #if USE_UE4_MEM_ALLOC FMemory::Free(Decoder); #else opus_multistream_encoder_destroy(Decoder); #endif #endif }
static void CloseEncoder(vlc_object_t *p_this) { encoder_t *enc = (encoder_t *)p_this; encoder_sys_t *sys = enc->p_sys; opus_multistream_encoder_destroy(sys->enc); if (sys->padding) block_Release(sys->padding); free(sys->buffer); free(sys); }
void krad_opus_encoder_destroy (krad_opus_t *krad_opus) { int c; for (c = 0; c < krad_opus->channels; c++) { krad_ringbuffer_free ( krad_opus->ringbuf[c] ); krad_ringbuffer_free ( krad_opus->resampled_ringbuf[c] ); free (krad_opus->resampled_samples[c]); free (krad_opus->samples[c]); free (krad_opus->read_samples[c]); src_delete (krad_opus->src_resampler[c]); } free (krad_opus->opustags_header); free (krad_opus->opus_header); opus_multistream_encoder_destroy (krad_opus->encoder); free (krad_opus); }
static gboolean gst_opus_enc_stop (GstAudioEncoder * benc) { GstOpusEnc *enc = GST_OPUS_ENC (benc); GST_DEBUG_OBJECT (enc, "stop"); enc->header_sent = FALSE; if (enc->state) { opus_multistream_encoder_destroy (enc->state); enc->state = NULL; } gst_tag_list_free (enc->tags); enc->tags = NULL; g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL); g_slist_free (enc->headers); enc->headers = NULL; gst_tag_setter_reset_tags (GST_TAG_SETTER (enc)); return TRUE; }
static int OpenEncoder(vlc_object_t *p_this) { encoder_t *enc = (encoder_t *)p_this; if (enc->fmt_out.i_codec != VLC_CODEC_OPUS) return VLC_EGENERIC; encoder_sys_t *sys = malloc(sizeof(*sys)); if (!sys) return VLC_ENOMEM; int status = VLC_SUCCESS; sys->buffer = NULL; sys->enc = NULL; enc->pf_encode_audio = Encode; enc->fmt_in.i_codec = VLC_CODEC_FL32; enc->fmt_in.audio.i_rate = /* Only 48kHz */ enc->fmt_out.audio.i_rate = 48000; enc->fmt_out.audio.i_channels = enc->fmt_in.audio.i_channels; OpusHeader header; if (opus_prepare_header(enc->fmt_out.audio.i_channels, enc->fmt_out.audio.i_rate, &header)) { msg_Err(enc, "Failed to prepare header."); status = VLC_ENOMEM; goto error; } /* needed for max encoded size calculation */ sys->nb_streams = header.nb_streams; int err; sys->enc = opus_multistream_surround_encoder_create(enc->fmt_in.audio.i_rate, enc->fmt_in.audio.i_channels, header.channel_mapping, &header.nb_streams, &header.nb_coupled, header.stream_map, OPUS_APPLICATION_AUDIO, &err); if (err != OPUS_OK) { msg_Err(enc, "Could not create encoder: error %d", err); sys->enc = NULL; status = VLC_EGENERIC; goto error; } /* TODO: vbr, bitrate, fec */ /* Buffer for incoming audio, since opus only accepts frame sizes that are multiples of 2.5ms */ enc->p_sys = sys; sys->buffer = malloc(OPUS_FRAME_SIZE * header.channels * sizeof(float)); if (!sys->buffer) { status = VLC_ENOMEM; goto error; } sys->i_nb_samples = 0; sys->i_samples_delay = 0; int ret = opus_multistream_encoder_ctl(enc->p_sys->enc, OPUS_GET_LOOKAHEAD(&sys->i_samples_delay)); if (ret != OPUS_OK) msg_Err(enc, "Unable to get number of lookahead samples: %s\n", opus_strerror(ret)); header.preskip = sys->i_samples_delay; /* Now that we have preskip, we can write the header to extradata */ if (opus_write_header((uint8_t **) &enc->fmt_out.p_extra, &enc->fmt_out.i_extra, &header)) { msg_Err(enc, "Failed to write header."); status = VLC_ENOMEM; goto error; } if (sys->i_samples_delay > 0) { const unsigned padding_samples = sys->i_samples_delay * enc->fmt_out.audio.i_channels; sys->padding = block_Alloc(padding_samples * sizeof(float)); if (!sys->padding) { status = VLC_ENOMEM; goto error; } sys->padding->i_nb_samples = sys->i_samples_delay; float *pad_ptr = (float *) sys->padding->p_buffer; memset(pad_ptr, 0, padding_samples * sizeof(float)); } else { sys->padding = NULL; } return status; error: if (sys->enc) opus_multistream_encoder_destroy(sys->enc); free(sys->buffer); free(sys); return status; }
static result_t encode_opus_file(char *filename, struct PCMReader *pcmreader, int quality, unsigned original_sample_rate) { const int multichannel = (pcmreader->channels > 2); const unsigned channel_mapping = (pcmreader->channels > 8 ? 255 : pcmreader->channels > 2); int stream_count; int coupled_stream_count; unsigned char stream_map[255]; int samples[BLOCK_SIZE * pcmreader->channels]; unsigned pcm_frames; result_t result = ENCODE_OK; FILE *output_file = NULL; ogg_stream_state ogg_stream; ogg_page ogg_page; OpusEncoder *opus_encoder = NULL; OpusMSEncoder *opus_ms_encoder = NULL; int error; opus_int16 *opus_samples = NULL; unsigned char opus_frame[OPUS_FRAME_LEN]; ogg_int64_t granulepos = 0; ogg_int64_t packetno = 0; opus_int32 preskip; /*open output file for writing*/ if ((output_file = fopen(filename, "w+b")) == NULL) { return ERR_IOERROR; } if (!multichannel) { if ((opus_encoder = opus_encoder_create(48000, pcmreader->channels, OPUS_APPLICATION_AUDIO, &error)) == NULL) { fclose(output_file); return ERR_ENCODER_INIT; } opus_encoder_ctl(opus_encoder, OPUS_SET_COMPLEXITY(quality)); opus_encoder_ctl(opus_encoder, OPUS_GET_LOOKAHEAD(&preskip)); } else { if ((opus_ms_encoder = opus_multistream_surround_encoder_create( 48000, pcmreader->channels, channel_mapping, &stream_count, &coupled_stream_count, stream_map, OPUS_APPLICATION_AUDIO, &error)) == NULL) { fclose(output_file); return ERR_ENCODER_INIT; } opus_multistream_encoder_ctl(opus_ms_encoder, OPUS_SET_COMPLEXITY(quality)); opus_multistream_encoder_ctl(opus_ms_encoder, OPUS_GET_LOOKAHEAD(&preskip)); } srand((unsigned)time(NULL)); ogg_stream_init(&ogg_stream, rand()); /*write header and comment packets to Ogg stream*/ { BitstreamRecorder *header = bw_open_bytes_recorder(BS_LITTLE_ENDIAN); BitstreamWriter *header_w =(BitstreamWriter*)header; BitstreamRecorder *comment = bw_open_bytes_recorder(BS_LITTLE_ENDIAN); BitstreamWriter *comment_w = (BitstreamWriter*)comment; int i; /*write header packet to Ogg stream*/ const char opushead[] = "OpusHead"; const char opuscomment[] = "OpusTags"; const char *vendor_string = opus_get_version_string(); const size_t vendor_string_len = strlen(vendor_string); ogg_packet packet_head; ogg_packet packet_tags; header_w->write_bytes(header_w, (uint8_t*)opushead, (unsigned)strlen(opushead)); header_w->write(header_w, 8, 1); /*version*/ header_w->write(header_w, 8, pcmreader->channels); header_w->write(header_w, 16, preskip); header_w->write(header_w, 32, original_sample_rate); header_w->write(header_w, 16, 0); /*output gain*/ header_w->write(header_w, 8, channel_mapping); if (channel_mapping != 0) { header_w->write(header_w, 8, stream_count); header_w->write(header_w, 8, coupled_stream_count); for (i = 0; i < pcmreader->channels; i++) { header_w->write(header_w, 8, stream_map[i]); } } packet_head.packet = malloc(header->bytes_written(header)); header->data(header, (uint8_t*)packet_head.packet); packet_head.bytes = header->bytes_written(header); packet_head.b_o_s = 1; packet_head.e_o_s = 0; packet_head.granulepos = 0; packet_head.packetno = packetno++; header->close(header); ogg_stream_packetin(&ogg_stream, &packet_head); for (i = ogg_stream_flush(&ogg_stream, &ogg_page); i != 0; i = ogg_stream_flush(&ogg_stream, &ogg_page)) { fwrite(ogg_page.header, 1, ogg_page.header_len, output_file); fwrite(ogg_page.body, 1, ogg_page.body_len, output_file); } free(packet_head.packet); /*write comment packet to Ogg stream*/ comment_w->write_bytes(comment_w, (uint8_t*)opuscomment, (unsigned)strlen(opuscomment)); comment_w->write(comment_w, 32, (unsigned)vendor_string_len); comment_w->write_bytes(comment_w, (uint8_t*)vendor_string, (unsigned)vendor_string_len); comment_w->write(comment_w, 32, 0); packet_tags.packet = malloc(comment->bytes_written(comment)); comment->data(comment, (uint8_t*)packet_tags.packet); packet_tags.bytes = comment->bytes_written(comment); packet_tags.b_o_s = 0; packet_tags.e_o_s = 0; packet_tags.granulepos = 0; packet_tags.packetno = packetno++; comment->close(comment); ogg_stream_packetin(&ogg_stream, &packet_tags); for (i = ogg_stream_flush(&ogg_stream, &ogg_page); i != 0; i = ogg_stream_flush(&ogg_stream, &ogg_page)) { fwrite(ogg_page.header, 1, ogg_page.header_len, output_file); fwrite(ogg_page.body, 1, ogg_page.body_len, output_file); } free(packet_tags.packet); } opus_samples = malloc(sizeof(opus_int16) * pcmreader->channels * BLOCK_SIZE); pcm_frames = pcmreader->read(pcmreader, BLOCK_SIZE, samples); if (!pcm_frames && (pcmreader->status != PCM_OK)) { result = ERR_PCMREADER; goto cleanup; } /*for each non-empty FrameList from PCMReader, encode Opus frame*/ while (pcm_frames) { const int short_framelist = (pcm_frames < BLOCK_SIZE); unsigned i; opus_int32 encoded_size; ogg_packet packet; granulepos += pcm_frames; /*pad FrameList with additional null samples if necessary*/ memset(samples + pcm_frames * pcmreader->channels, 0, sizeof(int) * (BLOCK_SIZE - pcm_frames) * pcmreader->channels); /*rearrange channels to Vorbis order if necessary*/ reorder_channels(pcmreader->channel_mask, BLOCK_SIZE, samples); /*place samples in interleaved buffer*/ for (i = 0; i < (pcm_frames * pcmreader->channels); i++) { opus_samples[i] = (opus_int16)samples[i]; } /*call opus_encode on interleaved buffer to get next packet*/ if (!multichannel) { encoded_size = opus_encode(opus_encoder, opus_samples, BLOCK_SIZE, opus_frame, OPUS_FRAME_LEN); } else { encoded_size = opus_multistream_encode(opus_ms_encoder, opus_samples, BLOCK_SIZE, opus_frame, OPUS_FRAME_LEN); } /*get next FrameList to encode*/ pcm_frames = pcmreader->read(pcmreader, BLOCK_SIZE, samples); if (!pcm_frames && (pcmreader->status != PCM_OK)) { result = ERR_PCMREADER; goto cleanup; } /*dump Opus packet to Ogg stream*/ /*do this *after* reading the next FrameList in order to detect the end of stream properly based on whether the FrameList has no frames*/ packet.packet = (unsigned char *)opus_frame; packet.bytes = encoded_size; packet.b_o_s = 0; packet.e_o_s = (short_framelist || (pcm_frames == 0)); packet.granulepos = granulepos; packet.packetno = packetno; ogg_stream_packetin(&ogg_stream, &packet); while (ogg_stream_pageout(&ogg_stream, &ogg_page)) { fwrite(ogg_page.header, 1, ogg_page.header_len, output_file); fwrite(ogg_page.body, 1, ogg_page.body_len, output_file); } } /*flush any remaining Ogg pages to disk*/ while (ogg_stream_flush(&ogg_stream, &ogg_page)) { fwrite(ogg_page.header, 1, ogg_page.header_len, output_file); fwrite(ogg_page.body, 1, ogg_page.body_len, output_file); } cleanup: fclose(output_file); ogg_stream_clear(&ogg_stream); if (!multichannel) { opus_encoder_destroy(opus_encoder); } else { opus_multistream_encoder_destroy(opus_ms_encoder); } free(opus_samples); return result; }