/***************************************************************************** * CloseDecoder: decoder destruction *****************************************************************************/ static void CloseEncoder(vlc_object_t *p_this) { encoder_t *p_enc = (encoder_t *)p_this; encoder_sys_t *p_sys = p_enc->p_sys; aacEncClose(&p_sys->handle); free(p_sys); }
static int aac_encode_close(AVCodecContext *avctx) { AACContext *s = avctx->priv_data; if (s->handle) aacEncClose(&s->handle); av_freep(&avctx->extradata); ff_af_queue_close(&s->afq); return 0; }
static void libfdk_destroy(void *data) { libfdk_encoder_t *enc = data; aacEncClose(&enc->fdkhandle); bfree(enc->packet_buffer); bfree(enc); blog(LOG_INFO, "libfdk_aac encoder destroyed"); }
static gboolean gst_fdkaacenc_stop (GstAudioEncoder * enc) { GstFdkAacEnc *self = GST_FDKAACENC (enc); GST_DEBUG_OBJECT (self, "stop"); if (self->enc) aacEncClose (&self->enc); return TRUE; }
static int aac_encode_close(AVCodecContext *avctx) { AACContext *s = avctx->priv_data; if (s->handle) aacEncClose(&s->handle); #if FF_API_OLD_ENCODE_AUDIO av_freep(&avctx->coded_frame); #endif av_freep(&avctx->extradata); ff_af_queue_close(&s->afq); return 0; }
static void AacEncoderDestroy(AacEncoderContext * _pAacCtx) { if (_pAacCtx == NULL) { return; } if (((FdkaacConfig *)_pAacCtx)->pConvertBuf != NULL) { free(((FdkaacConfig *)_pAacCtx)->pConvertBuf); } if (aacEncClose(&((FdkaacConfig *)_pAacCtx)->pEncoder) != AACENC_OK) { return; } return; }
AACFileWriter::~AACFileWriter() { if(m_advance_samples > 0) { m_in_args.numInSamples = m_advance_samples * sizeof( int16_t ) / m_channel; m_encinBuf.bufs = (void **)&m_pInputbuf; m_in_bufsize = m_advance_samples * sizeof( int16_t ); auto ret = aacEncEncode( m_hAacEncoder, &m_encinBuf, &m_encoutBuf, &m_in_args, &m_out_args ); if(ret != AACENC_OK) { return; } if(m_out_args.numOutBytes > 0) { fwrite( m_outofbyte, 1, m_out_args.numOutBytes, m_aacfile ); } } m_in_bufsize = 0; m_encinBuf.bufs = nullptr; m_in_args.numInSamples = -1; auto ret = aacEncEncode( m_hAacEncoder, &m_encinBuf, &m_encoutBuf, &m_in_args, &m_out_args ); if(ret != AACENC_OK) { return; } if(m_out_args.numOutBytes > 0) { fwrite( m_outofbyte, 1, m_out_args.numOutBytes, m_aacfile ); } if(m_aacfile) fclose( m_aacfile ); m_aacfile = nullptr; if(m_outofbyte) delete[] m_outofbyte; if(m_pInputbuf) delete[] m_pInputbuf; aacEncClose( &m_hAacEncoder ); }
SoftAACEncoder2::~SoftAACEncoder2() { aacEncClose(&mAACEncoder); onReset(); }
int main(int argc, char *argv[]) { int bitrate = 64000; int ch; const char *infile, *outfile; FILE *out; void *wav; int format, sample_rate, channels, bits_per_sample; int input_size; uint8_t* input_buf; int16_t* convert_buf; int aot = 2; int afterburner = 1; int eld_sbr = 0; int vbr = 0; HANDLE_AACENCODER handle; CHANNEL_MODE mode; AACENC_InfoStruct info = { 0 }; while ((ch = getopt(argc, argv, "r:t:a:s:v:")) != -1) { switch (ch) { case 'r': bitrate = atoi(optarg); break; case 't': aot = atoi(optarg); break; case 'a': afterburner = atoi(optarg); break; case 's': eld_sbr = atoi(optarg); break; case 'v': vbr = atoi(optarg); break; case '?': default: usage(argv[0]); return 1; } } if (argc - optind < 2) { usage(argv[0]); return 1; } infile = argv[optind]; outfile = argv[optind + 1]; wav = wav_read_open(infile); if (!wav) { fprintf(stderr, "Unable to open wav file %s\n", infile); return 1; } if (!wav_get_header(wav, &format, &channels, &sample_rate, &bits_per_sample, NULL)) { fprintf(stderr, "Bad wav file %s\n", infile); return 1; } if (format != 1) { fprintf(stderr, "Unsupported WAV format %d\n", format); return 1; } if (bits_per_sample != 16) { fprintf(stderr, "Unsupported WAV sample depth %d\n", bits_per_sample); return 1; } switch (channels) { case 1: mode = MODE_1; break; case 2: mode = MODE_2; break; case 3: mode = MODE_1_2; break; case 4: mode = MODE_1_2_1; break; case 5: mode = MODE_1_2_2; break; case 6: mode = MODE_1_2_2_1; break; default: fprintf(stderr, "Unsupported WAV channels %d\n", channels); return 1; } if (aacEncOpen(&handle, 0, channels) != AACENC_OK) { fprintf(stderr, "Unable to open encoder\n"); return 1; } if (aacEncoder_SetParam(handle, AACENC_AOT, aot) != AACENC_OK) { fprintf(stderr, "Unable to set the AOT\n"); return 1; } if (aot == 39 && eld_sbr) { if (aacEncoder_SetParam(handle, AACENC_SBR_MODE, 1) != AACENC_OK) { fprintf(stderr, "Unable to set SBR mode for ELD\n"); return 1; } } if (aacEncoder_SetParam(handle, AACENC_SAMPLERATE, sample_rate) != AACENC_OK) { fprintf(stderr, "Unable to set the AOT\n"); return 1; } if (aacEncoder_SetParam(handle, AACENC_CHANNELMODE, mode) != AACENC_OK) { fprintf(stderr, "Unable to set the channel mode\n"); return 1; } if (aacEncoder_SetParam(handle, AACENC_CHANNELORDER, 1) != AACENC_OK) { fprintf(stderr, "Unable to set the wav channel order\n"); return 1; } if (vbr) { if (aacEncoder_SetParam(handle, AACENC_BITRATEMODE, vbr) != AACENC_OK) { fprintf(stderr, "Unable to set the VBR bitrate mode\n"); return 1; } } else { if (aacEncoder_SetParam(handle, AACENC_BITRATE, bitrate) != AACENC_OK) { fprintf(stderr, "Unable to set the bitrate\n"); return 1; } } if (aacEncoder_SetParam(handle, AACENC_TRANSMUX, 2) != AACENC_OK) { fprintf(stderr, "Unable to set the ADTS transmux\n"); return 1; } if (aacEncoder_SetParam(handle, AACENC_AFTERBURNER, afterburner) != AACENC_OK) { fprintf(stderr, "Unable to set the afterburner mode\n"); return 1; } if (aacEncEncode(handle, NULL, NULL, NULL, NULL) != AACENC_OK) { fprintf(stderr, "Unable to initialize the encoder\n"); return 1; } if (aacEncInfo(handle, &info) != AACENC_OK) { fprintf(stderr, "Unable to get the encoder info\n"); return 1; } out = fopen(outfile, "wb"); if (!out) { perror(outfile); return 1; } input_size = channels*2*info.frameLength; input_buf = (uint8_t*) malloc(input_size); convert_buf = (int16_t*) malloc(input_size); while (1) { AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 }; AACENC_InArgs in_args = { 0 }; AACENC_OutArgs out_args = { 0 }; int in_identifier = IN_AUDIO_DATA; int in_size, in_elem_size; int out_identifier = OUT_BITSTREAM_DATA; int out_size, out_elem_size; int read, i; void *in_ptr, *out_ptr; uint8_t outbuf[20480]; AACENC_ERROR err; read = wav_read_data(wav, input_buf, input_size); for (i = 0; i < read/2; i++) { const uint8_t* in = &input_buf[2*i]; convert_buf[i] = in[0] | (in[1] << 8); } if (read <= 0) { in_args.numInSamples = -1; } else { in_ptr = convert_buf; in_size = read; in_elem_size = 2; in_args.numInSamples = read/2; in_buf.numBufs = 1; in_buf.bufs = &in_ptr; in_buf.bufferIdentifiers = &in_identifier; in_buf.bufSizes = &in_size; in_buf.bufElSizes = &in_elem_size; } out_ptr = outbuf; out_size = sizeof(outbuf); out_elem_size = 1; out_buf.numBufs = 1; out_buf.bufs = &out_ptr; out_buf.bufferIdentifiers = &out_identifier; out_buf.bufSizes = &out_size; out_buf.bufElSizes = &out_elem_size; if ((err = aacEncEncode(handle, &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) { if (err == AACENC_ENCODE_EOF) break; fprintf(stderr, "Encoding failed\n"); return 1; } if (out_args.numOutBytes == 0) continue; fwrite(outbuf, 1, out_args.numOutBytes, out); } free(input_buf); free(convert_buf); fclose(out); wav_read_close(wav); aacEncClose(&handle); return 0; }
SoftAACEncoder2::~SoftAACEncoder2() { aacEncClose(&mAACEncoder); delete[] mInputFrame; mInputFrame = NULL; }
static gboolean gst_fdkaacenc_set_format (GstAudioEncoder * enc, GstAudioInfo * info) { GstFdkAacEnc *self = GST_FDKAACENC (enc); gboolean ret = FALSE; GstCaps *allowed_caps; GstCaps *src_caps; AACENC_ERROR err; gint transmux = 0, aot = AOT_AAC_LC; gint mpegversion = 4; CHANNEL_MODE channel_mode; AACENC_InfoStruct enc_info = { 0 }; gint bitrate; if (self->enc) { /* drain */ gst_fdkaacenc_handle_frame (enc, NULL); aacEncClose (&self->enc); } allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (self)); GST_DEBUG_OBJECT (self, "allowed caps: %" GST_PTR_FORMAT, allowed_caps); if (allowed_caps && gst_caps_get_size (allowed_caps) > 0) { GstStructure *s = gst_caps_get_structure (allowed_caps, 0); const gchar *str = NULL; if ((str = gst_structure_get_string (s, "stream-format"))) { if (strcmp (str, "adts") == 0) { GST_DEBUG_OBJECT (self, "use ADTS format for output"); transmux = 2; } else if (strcmp (str, "adif") == 0) { GST_DEBUG_OBJECT (self, "use ADIF format for output"); transmux = 1; } else if (strcmp (str, "raw") == 0) { GST_DEBUG_OBJECT (self, "use RAW format for output"); transmux = 0; } } gst_structure_get_int (s, "mpegversion", &mpegversion); } if (allowed_caps) gst_caps_unref (allowed_caps); err = aacEncOpen (&self->enc, 0, GST_AUDIO_INFO_CHANNELS (info)); if (err != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to open encoder: %d\n", err); return FALSE; } aot = AOT_AAC_LC; if ((err = aacEncoder_SetParam (self->enc, AACENC_AOT, aot)) != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to set AOT %d: %d\n", aot, err); return FALSE; } if ((err = aacEncoder_SetParam (self->enc, AACENC_SAMPLERATE, GST_AUDIO_INFO_RATE (info))) != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to set sample rate %d: %d\n", GST_AUDIO_INFO_RATE (info), err); return FALSE; } if (GST_AUDIO_INFO_CHANNELS (info) == 1) { channel_mode = MODE_1; self->need_reorder = FALSE; self->aac_positions = NULL; } else { guint64 in_channel_mask, out_channel_mask; gint i; for (i = 0; i < G_N_ELEMENTS (channel_layouts); i++) { if (channel_layouts[i].channels != GST_AUDIO_INFO_CHANNELS (info)) continue; gst_audio_channel_positions_to_mask (&GST_AUDIO_INFO_POSITION (info, 0), GST_AUDIO_INFO_CHANNELS (info), FALSE, &in_channel_mask); gst_audio_channel_positions_to_mask (channel_layouts[i].positions, channel_layouts[i].channels, FALSE, &out_channel_mask); if (in_channel_mask == out_channel_mask) { channel_mode = channel_layouts[i].mode; self->need_reorder = memcmp (channel_layouts[i].positions, &GST_AUDIO_INFO_POSITION (info, 0), GST_AUDIO_INFO_CHANNELS (info) * sizeof (GstAudioChannelPosition)) != 0; self->aac_positions = channel_layouts[i].positions; break; } } if (i == G_N_ELEMENTS (channel_layouts)) { GST_ERROR_OBJECT (self, "Couldn't find a valid channel layout"); return FALSE; } } if ((err = aacEncoder_SetParam (self->enc, AACENC_CHANNELMODE, channel_mode)) != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to set channel mode %d: %d", channel_mode, err); return FALSE; } /* MPEG channel order */ if ((err = aacEncoder_SetParam (self->enc, AACENC_CHANNELORDER, 0)) != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to set channel order %d: %d", channel_mode, err); return FALSE; } bitrate = self->bitrate; /* See * http://wiki.hydrogenaud.io/index.php?title=Fraunhofer_FDK_AAC#Recommended_Sampling_Rate_and_Bitrate_Combinations */ if (bitrate == 0) { if (GST_AUDIO_INFO_CHANNELS (info) == 1) { if (GST_AUDIO_INFO_RATE (info) < 16000) { bitrate = 8000; } else if (GST_AUDIO_INFO_RATE (info) == 16000) { bitrate = 16000; } else if (GST_AUDIO_INFO_RATE (info) < 32000) { bitrate = 24000; } else if (GST_AUDIO_INFO_RATE (info) == 32000) { bitrate = 32000; } else if (GST_AUDIO_INFO_RATE (info) <= 44100) { bitrate = 56000; } else { bitrate = 160000; } } else if (GST_AUDIO_INFO_CHANNELS (info) == 2) { if (GST_AUDIO_INFO_RATE (info) < 16000) { bitrate = 16000; } else if (GST_AUDIO_INFO_RATE (info) == 16000) { bitrate = 24000; } else if (GST_AUDIO_INFO_RATE (info) < 22050) { bitrate = 32000; } else if (GST_AUDIO_INFO_RATE (info) < 32000) { bitrate = 40000; } else if (GST_AUDIO_INFO_RATE (info) == 32000) { bitrate = 96000; } else if (GST_AUDIO_INFO_RATE (info) <= 44100) { bitrate = 112000; } else { bitrate = 320000; } } else { /* 5, 5.1 */ if (GST_AUDIO_INFO_RATE (info) < 32000) { bitrate = 160000; } else if (GST_AUDIO_INFO_RATE (info) <= 44100) { bitrate = 240000; } else { bitrate = 320000; } } } if ((err = aacEncoder_SetParam (self->enc, AACENC_TRANSMUX, transmux)) != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to set transmux %d: %d", transmux, err); return FALSE; } if ((err = aacEncoder_SetParam (self->enc, AACENC_BITRATE, bitrate)) != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to set bitrate %d: %d", bitrate, err); return FALSE; } if ((err = aacEncEncode (self->enc, NULL, NULL, NULL, NULL)) != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to initialize encoder: %d", err); return FALSE; } if ((err = aacEncInfo (self->enc, &enc_info)) != AACENC_OK) { GST_ERROR_OBJECT (self, "Unable to get encoder info: %d", err); return FALSE; } gst_audio_encoder_set_frame_max (enc, 1); gst_audio_encoder_set_frame_samples_min (enc, enc_info.frameLength); gst_audio_encoder_set_frame_samples_max (enc, enc_info.frameLength); gst_audio_encoder_set_hard_min (enc, FALSE); self->outbuf_size = enc_info.maxOutBufBytes; self->samples_per_frame = enc_info.frameLength; src_caps = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, mpegversion, "channels", G_TYPE_INT, GST_AUDIO_INFO_CHANNELS (info), "framed", G_TYPE_BOOLEAN, TRUE, "rate", G_TYPE_INT, GST_AUDIO_INFO_RATE (info), NULL); /* raw */ if (transmux == 0) { GstBuffer *codec_data = gst_buffer_new_wrapped (g_memdup (enc_info.confBuf, enc_info.confSize), enc_info.confSize); gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER, codec_data, "stream-format", G_TYPE_STRING, "raw", NULL); gst_buffer_unref (codec_data); } else if (transmux == 1) { gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "adif", NULL); } else if (transmux == 2) { gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "adts", NULL); } else { g_assert_not_reached (); } gst_codec_utils_aac_caps_set_level_and_profile (src_caps, enc_info.confBuf, enc_info.confSize); ret = gst_audio_encoder_set_output_format (enc, src_caps); gst_caps_unref (src_caps); return ret; }
static void *libfdk_create(obs_data_t settings, obs_encoder_t encoder) { bool hasFdkHandle = false; libfdk_encoder_t *enc = 0; int bitrate = (int)obs_data_get_int(settings, "bitrate") * 1000; int afterburner = obs_data_get_bool(settings, "afterburner") ? 1 : 0; audio_t audio = obs_encoder_audio(encoder); int mode = 0; AACENC_ERROR err; if (!bitrate) { blog(LOG_ERROR, "Invalid bitrate"); return NULL; } enc = bzalloc(sizeof(libfdk_encoder_t)); enc->encoder = encoder; enc->channels = (int)audio_output_get_channels(audio); enc->sample_rate = audio_output_get_sample_rate(audio); switch(enc->channels) { case 1: mode = MODE_1; break; case 2: mode = MODE_2; break; case 3: mode = MODE_1_2; break; case 4: mode = MODE_1_2_1; break; case 5: mode = MODE_1_2_2; break; case 6: mode = MODE_1_2_2_1; break; default: blog(LOG_ERROR, "Invalid channel count"); goto fail; } CHECK_LIBFDK(aacEncOpen(&enc->fdkhandle, 0, enc->channels)); hasFdkHandle = true; CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_AOT, 2)); // MPEG-4 AAC-LC CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_SAMPLERATE, enc->sample_rate)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELMODE, mode)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_CHANNELORDER, 1)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATEMODE, 0)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_BITRATE, bitrate)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_TRANSMUX, 0)); CHECK_LIBFDK(aacEncoder_SetParam(enc->fdkhandle, AACENC_AFTERBURNER, afterburner)); CHECK_LIBFDK(aacEncEncode(enc->fdkhandle, NULL, NULL, NULL, NULL)); CHECK_LIBFDK(aacEncInfo(enc->fdkhandle, &enc->info)); enc->frame_size_bytes = enc->info.frameLength * 2 * enc->channels; enc->packet_buffer_size = enc->channels * 768; if(enc->packet_buffer_size < 8192) enc->packet_buffer_size = 8192; enc->packet_buffer = bmalloc(enc->packet_buffer_size); blog(LOG_INFO, "libfdk_aac encoder created"); blog(LOG_INFO, "libfdk_aac bitrate: %d, channels: %d", bitrate / 1000, enc->channels); return enc; fail: if(hasFdkHandle) aacEncClose(&enc->fdkhandle); if(enc->packet_buffer) bfree(enc->packet_buffer); if(enc) bfree(enc); blog(LOG_WARNING, "libfdk_aac encoder creation failed"); return 0; }
int aacenc_init(HANDLE_AACENCODER *encoder, const aacenc_param_t *params, const pcm_sample_description_t *format, AACENC_InfoStruct *info) { int channel_mode; int aot; LIB_INFO lib_info; *encoder = 0; aacenc_get_lib_info(&lib_info); if ((channel_mode = aacenc_channel_mode(format)) == 0) { fprintf(stderr, "ERROR: unsupported channel layout\n"); goto FAIL; } if (aacEncOpen(encoder, 0, 0) != AACENC_OK) { fprintf(stderr, "ERROR: aacEncOpen() failed\n"); goto FAIL; } aot = (params->profile ? params->profile : AOT_AAC_LC); if (aacEncoder_SetParam(*encoder, AACENC_AOT, aot) != AACENC_OK) { fprintf(stderr, "ERROR: unsupported profile\n"); goto FAIL; } if (params->bitrate_mode == 0) aacEncoder_SetParam(*encoder, AACENC_BITRATE, params->bitrate); else if (aacEncoder_SetParam(*encoder, AACENC_BITRATEMODE, params->bitrate_mode) != AACENC_OK) { fprintf(stderr, "ERROR: unsupported bitrate mode\n"); goto FAIL; } if (aacEncoder_SetParam(*encoder, AACENC_SAMPLERATE, format->sample_rate) != AACENC_OK) { fprintf(stderr, "ERROR: unsupported sample rate\n"); goto FAIL; } if (aacEncoder_SetParam(*encoder, AACENC_CHANNELMODE, channel_mode) != AACENC_OK) { fprintf(stderr, "ERROR: unsupported channel mode\n"); goto FAIL; } aacEncoder_SetParam(*encoder, AACENC_BANDWIDTH, params->bandwidth); aacEncoder_SetParam(*encoder, AACENC_CHANNELORDER, 1); aacEncoder_SetParam(*encoder, AACENC_AFTERBURNER, !!params->afterburner); aacEncoder_SetParam(*encoder, AACENC_SBR_MODE, params->lowdelay_sbr); #if AACENCODER_LIB_VL0 > 3 || (AACENCODER_LIB_VL0==3 && AACENCODER_LIB_VL1>=4) if (lib_info.version > 0x03040800) aacEncoder_SetParam(*encoder, AACENC_SBR_RATIO, params->sbr_ratio); #endif if (aacEncoder_SetParam(*encoder, AACENC_TRANSMUX, params->transport_format) != AACENC_OK) { fprintf(stderr, "ERROR: unsupported transport format\n"); goto FAIL; } if (aacEncoder_SetParam(*encoder, AACENC_SIGNALING_MODE, params->sbr_signaling) != AACENC_OK) { fprintf(stderr, "ERROR: failed to set SBR signaling mode\n"); goto FAIL; } if (params->adts_crc_check) aacEncoder_SetParam(*encoder, AACENC_PROTECTION, 1); if (params->header_period) aacEncoder_SetParam(*encoder, AACENC_HEADER_PERIOD, params->header_period); if (aacEncEncode(*encoder, 0, 0, 0, 0) != AACENC_OK) { fprintf(stderr, "ERROR: encoder initialization failed\n"); goto FAIL; } if (aacEncInfo(*encoder, info) != AACENC_OK) { fprintf(stderr, "ERROR: cannot retrieve encoder info\n"); goto FAIL; } return 0; FAIL: if (encoder) aacEncClose(encoder); return -1; }