/*初始化*/ jlong Java_com_vvku_aacencoder_heaacEncInterface_init(JNIEnv* env, jobject thiz, jint samplerate, jint channels, jint bitrate, jint bandwidth, jlongArray param_out, jstring input_file) { __android_log_print(ANDROID_LOG_INFO, "encoderInterface native", "begin init"); jlong *info = (jlong*)(*env)->GetLongArrayElements(env, param_out, 0); Encoder * en = (Encoder *) malloc(sizeof(Encoder)); en->inputInfo = (WavInfo *) malloc(sizeof(WavInfo)); en->bitrate = 16000; en->sampleRateAAC = 44100; unsigned char* wav_file = (char*)(*env)->GetStringUTFChars(env, input_file, 0); FILE *inputfile; inputfile = AuChannelOpen(wav_file, en->inputInfo); if(bitrate > 0){ en->bitrate = bitrate * 1000; } if(!inputfile){ en->inputInfo->nChannels = 2; en->inputInfo->sampleRate = 32000; } if(samplerate > 0){ en->inputInfo->sampleRate = samplerate; } if(channels > 0){ en->inputInfo->nChannels = channels; } en->hEncoder = aacplusEncOpen(en->inputInfo->sampleRate, en->inputInfo->nChannels, &en->inputSamples, &en->maxOutputBytes); info[0] = en->inputSamples*2; info[1] = en->maxOutputBytes; en->cfg = aacplusEncGetCurrentConfiguration(en->hEncoder); en->cfg->bitRate = en->bitrate; en->cfg->bandWidth = 0; en->cfg->outputFormat = 0; // 设置为1的话,会加上adts头,直接保存成aac文件的时候需要 en->cfg->nChannelsOut = en->inputInfo->nChannels; //en->cfg->inputFormat = AACPLUS_INPUT_FLOAT; int ret = 0; if((ret = aacplusEncSetConfiguration(en->hEncoder, en->cfg)) == 0) { __android_log_print(ANDROID_LOG_INFO, "encoderInterface native", "Init failed."); if(inputfile) AuChannelClose(inputfile); (*env)->ReleaseLongArrayElements(env, param_out, info, 0); (*env)->ReleaseStringUTFChars(env, input_file, wav_file); return -2; } if(inputfile) AuChannelClose(inputfile); (*env)->ReleaseLongArrayElements(env, param_out, info, 0); (*env)->ReleaseStringUTFChars(env, input_file, wav_file); __android_log_print(ANDROID_LOG_INFO, "encoderInterface native", "init success."); return (jlong) en; }
/*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ bool aacPlusEncoder :: open ( void ) throw ( Exception ) { if ( isOpen() ) { close(); } // open the underlying sink if ( !sink->open() ) { throw Exception( __FILE__, __LINE__, "aacplus lib opening underlying sink error"); } reportEvent(1, "Using aacplus codec"); encoderHandle = aacplusEncOpen(getOutSampleRate(), getInChannel(), &inputSamples, &maxOutputBytes); aacplusEncConfiguration * aacplusConfig; aacplusConfig = aacplusEncGetCurrentConfiguration(encoderHandle); aacplusConfig->bitRate = getOutBitrate() * 1000; aacplusConfig->bandWidth = lowpass; aacplusConfig->outputFormat = 1; aacplusConfig->inputFormat = AACPLUS_INPUT_16BIT; aacplusConfig->nChannelsOut = getOutChannel(); if (!aacplusEncSetConfiguration(encoderHandle, aacplusConfig)) { throw Exception(__FILE__, __LINE__, "error configuring libaacplus library"); } // initialize the resampling coverter if needed if ( converter ) { #ifdef HAVE_SRC_LIB converterData.input_frames = 4096/((getInBitsPerSample() / 8) * getInChannel()); converterData.data_in = new float[converterData.input_frames*getInChannel()]; converterData.output_frames = (int) (converterData.input_frames * resampleRatio + 1); if ((int) inputSamples > getInChannel() * converterData.output_frames) { resampledOffset = new float[2 * inputSamples]; } else { resampledOffset = new float[2 * getInChannel() * converterData.input_frames]; } converterData.src_ratio = resampleRatio; converterData.end_of_input = 0; #else converter->initialize( resampleRatio, getInChannel()); //needed 2x(converted input samples) to handle offsets int outCount = 2 * getInChannel() * (inputSamples + 1); if (resampleRatio > 1) outCount = (int) (outCount * resampleRatio); resampledOffset = new short int[outCount]; #endif resampledOffsetSize = 0; } aacplusOpen = true; reportEvent(10, "nChannelsAAC", aacplusConfig->nChannelsOut); reportEvent(10, "sampleRateAAC", aacplusConfig->sampleRate); reportEvent(10, "inSamples", inputSamples); return true; }
int main(int argc, char *argv[]) { WavInfo inputInfo; FILE *inputFile = NULL; FILE *hADTSFile; int error; int bEncodeMono = 0; int frmCnt = 0; /* * parse command line arguments */ if (argc != 5) { fprintf(stderr, "\nUsage: %s <wav_file> <bitstream_file> <bitrate> <(m)ono/(s)tereo>\n", argv[0]); fprintf(stderr, "\nExample: %s input.wav out.aac 24000 s\n", argv[0]); return 0; } if ( strcmp (argv[4],"m") == 0 ) { bEncodeMono = 1; } else { if ( strcmp (argv[4],"s") != 0 ) { fprintf(stderr, "\nWrong mode %s, use either (m)ono or (s)tereo\n", argv[4]); return 0; } } fflush(stdout); inputFile = AuChannelOpen (argv[1], &inputInfo); if(inputFile == NULL){ fprintf(stderr,"could not open %s\n",argv[1]); exit(10); } if (inputInfo.nChannels==1 && !bEncodeMono) { fprintf(stderr,"Need stereo input for stereo coding mode !\n"); exit(10); } if (strcmp(argv[2],"-")==0) hADTSFile=stdout; else hADTSFile = fopen(argv[2], "wb"); if(!hADTSFile) { fprintf(stderr, "\nFailed to create ADTS file\n") ; exit(10); } /* Be verbose */ unsigned long inputSamples=0; unsigned long maxOutputBytes=0; aacplusEncHandle hEncoder = aacplusEncOpen(inputInfo.sampleRate, inputInfo.nChannels, &inputSamples, &maxOutputBytes); aacplusEncConfiguration *cfg = aacplusEncGetCurrentConfiguration(hEncoder); cfg->bitRate = atoi(argv[3]); cfg->bandWidth = 0; cfg->outputFormat = 1; cfg->nChannelsOut = bEncodeMono ? 1 : inputInfo.nChannels; if(inputInfo.aFmt == WAV_FORMAT_FLOAT){ cfg->inputFormat = AACPLUS_INPUT_FLOAT; } fprintf(stdout,"input file %s: \nsr = %d, nc = %d fmt = %d\n\n", argv[1], inputInfo.sampleRate, inputInfo.nChannels, inputInfo.aFmt); fprintf(stdout,"output file %s: \nbr = %d inputSamples = %lu maxOutputBytes = %lu nc = %d m = %d\n\n", argv[2], cfg->bitRate, inputSamples, maxOutputBytes, cfg->nChannelsOut, bEncodeMono); fflush(stdout); int ret = 0; if((ret = aacplusEncSetConfiguration(hEncoder, cfg)) == 0) { fprintf(stdout,"setting cfg failed\n", ret); return -1; } uint8_t *outputBuffer = malloc(maxOutputBytes); int32_t *TimeDataPcm; if(inputInfo.aFmt == WAV_FORMAT_FLOAT) { TimeDataPcm = calloc(inputSamples, sizeof(float)); } else { TimeDataPcm = calloc(inputSamples, sizeof(short)); } int stopLoop = 0; int bytes = 0; do { int numSamplesRead = 0; if(inputInfo.aFmt == WAV_FORMAT_FLOAT) { if ( AuChannelReadFloat(inputFile, (float *) TimeDataPcm, inputSamples, &numSamplesRead) > 0) { stopLoop = 1; break; } } else { if ( AuChannelReadShort(inputFile, (short *) TimeDataPcm, inputSamples, &numSamplesRead) > 0) { stopLoop = 1; break; } } if(numSamplesRead < inputSamples) { stopLoop = 1; break; } bytes = aacplusEncEncode(hEncoder, (int32_t *) TimeDataPcm, numSamplesRead, outputBuffer, maxOutputBytes); if(bytes > 0) fwrite(outputBuffer, bytes, 1, hADTSFile); frmCnt++; fprintf(stderr,"[%d]\r",frmCnt); fflush(stderr); } while (!stopLoop && bytes >= 0); fprintf(stderr,"\n"); fflush(stderr); printf("\nencoding finished\n"); aacplusEncClose(hEncoder); fclose(hADTSFile); free(outputBuffer); free(TimeDataPcm); return 0; }
static av_cold int aacPlus_encode_init(AVCodecContext *avctx) { aacPlusAudioContext *s = avctx->priv_data; aacplusEncConfiguration *aacplus_cfg; unsigned long samples_input, max_bytes_output; /* number of channels */ if (avctx->channels < 1 || avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); return -1; } s->aacplus_handle = aacplusEncOpen(avctx->sample_rate, avctx->channels, &samples_input, &max_bytes_output); if(!s->aacplus_handle) { av_log(avctx, AV_LOG_ERROR, "can't open encoder\n"); return -1; } /* check aacplus version */ aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle); /* put the options in the configuration struct */ if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) { av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile); aacplusEncClose(s->aacplus_handle); return -1; } aacplus_cfg->bitRate = avctx->bit_rate; aacplus_cfg->bandWidth = avctx->cutoff; aacplus_cfg->outputFormat = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER); aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT; if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) { av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n"); return -1; } avctx->frame_size = samples_input / avctx->channels; avctx->coded_frame= avcodec_alloc_frame(); avctx->coded_frame->key_frame= 1; /* Set decoder specific info */ avctx->extradata_size = 0; if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { unsigned char *buffer = NULL; unsigned long decoder_specific_info_size; if (aacplusEncGetDecoderSpecificInfo(s->aacplus_handle, &buffer, &decoder_specific_info_size) == 1) { avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE); avctx->extradata_size = decoder_specific_info_size; memcpy(avctx->extradata, buffer, avctx->extradata_size); } #undef free free(buffer); #define free please_use_av_free } return 0; }