static int aacPlus_encode_frame(AVCodecContext *avctx, unsigned char *frame, int buf_size, void *data) { aacPlusAudioContext *s = avctx->priv_data; int bytes_written; bytes_written = aacplusEncEncode(s->aacplus_handle, data, avctx->frame_size * avctx->channels, frame, buf_size); return bytes_written; }
/*编码一帧数据*/ jint Java_com_vvku_aacencoder_heaacEncInterface_encodeframe(JNIEnv* env, jobject thiz, jlong handle, jbyteArray in, jint samplesRead, jbyteArray out) { Encoder * en = (Encoder *) handle; jbyte * pcmbuf = (jbyte*)(*env)->GetByteArrayElements(env, in, 0); jbyte * outputBuffer= (jbyte*)(*env)->GetByteArrayElements(env, out, 0); short *in_buf = (short*) pcmbuf; char out_buf[en->maxOutputBytes]; memset(out_buf, 0, sizeof(out_buf)); int numOutBytes=0; numOutBytes = aacplusEncEncode(en->hEncoder, (int32_t *)in_buf, en->inputSamples, out_buf, en->maxOutputBytes); memcpy(outputBuffer, out_buf, numOutBytes); (*env)->ReleaseByteArrayElements(env,out,outputBuffer,0); //释放内存,防止泄露 (*env)->ReleaseByteArrayElements(env,in,pcmbuf,0); return numOutBytes; }
/*------------------------------------------------------------------------------ * Write data to the encoder *----------------------------------------------------------------------------*/ unsigned int aacPlusEncoder :: write ( const void * buf, unsigned int len ) throw ( Exception ) { if ( !isOpen() || len == 0) { return 0; } unsigned int channels = getInChannel(); unsigned int bitsPerSample = getInBitsPerSample(); unsigned int sampleSize = (bitsPerSample / 8) * channels; unsigned char * b = (unsigned char*) buf; unsigned int processed = len - (len % sampleSize); unsigned int nSamples = processed / sampleSize; unsigned char * aacplusBuf = new unsigned char[maxOutputBytes]; int samples = (int) nSamples * channels; int processedSamples = 0; if ( converter ) { unsigned int converted; #ifdef HAVE_SRC_LIB src_short_to_float_array ((short *) b, converterData.data_in, samples); converterData.input_frames = nSamples; converterData.data_out = resampledOffset + (resampledOffsetSize * channels); int srcError = src_process (converter, &converterData); if (srcError) throw Exception (__FILE__, __LINE__, "libsamplerate error: ", src_strerror (srcError)); converted = converterData.output_frames_gen; #else int inCount = nSamples; short int * shortBuffer = new short int[samples]; int outCount = (int) (inCount * resampleRatio); Util::conv( bitsPerSample, b, processed, shortBuffer, isInBigEndian()); converted = converter->resample( inCount, outCount+1, shortBuffer, &resampledOffset[resampledOffsetSize*channels]); delete[] shortBuffer; #endif resampledOffsetSize += converted; // encode samples (if enough) while(resampledOffsetSize - processedSamples >= inputSamples/channels) { int outputBytes; #ifdef HAVE_SRC_LIB short *shortData = new short[inputSamples]; src_float_to_short_array(resampledOffset + (processedSamples * channels), shortData, inputSamples) ; outputBytes = aacplusEncEncode(encoderHandle, (int32_t*) shortData, inputSamples, aacplusBuf, maxOutputBytes); delete [] shortData; #else outputBytes = aacplusEncEncode(encoderHandle, (int32_t*) &resampledOffset[processedSamples*channels], inputSamples, aacplusBuf, maxOutputBytes); #endif getSink()->write(aacplusBuf, outputBytes); processedSamples+=inputSamples/channels; } if (processedSamples && (int) resampledOffsetSize >= processedSamples) { resampledOffsetSize -= processedSamples; //move least part of resampled data to beginning if(resampledOffsetSize) #ifdef HAVE_SRC_LIB resampledOffset = (float *) memmove(resampledOffset, &resampledOffset[processedSamples*channels], resampledOffsetSize*channels*sizeof(float)); #else resampledOffset = (short *) memmove(resampledOffset, &resampledOffset[processedSamples*channels], resampledOffsetSize*sampleSize); #endif } } else { while (processedSamples < samples) { int outputBytes; int inSamples = samples - processedSamples < (int) inputSamples ? samples - processedSamples : inputSamples; outputBytes = aacplusEncEncode(encoderHandle, (int32_t*) (b + processedSamples/sampleSize), inSamples, aacplusBuf, maxOutputBytes); getSink()->write(aacplusBuf, outputBytes); processedSamples += inSamples; } } delete[] aacplusBuf; // return processedSamples; return samples * sampleSize; }
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; }