int FAACEncoder::Init(int nSampleRate, int nChannels) { if (IsWorking()) { return 0; } m_nSampleRate = nSampleRate; m_nChannels = nChannels; m_hfaac = faacEncOpen(m_nSampleRate, m_nChannels, &m_nInputSamples, &m_nMaxOutputBytes); if (m_hfaac!=NULL) { m_pfaacconf = faacEncGetCurrentConfiguration(m_hfaac); m_pfaacconf->inputFormat = FAAC_INPUT_16BIT; m_pfaacconf->outputFormat=1;//0raw 1adst m_pfaacconf->useTns=true; m_pfaacconf->useLfe=false; m_pfaacconf->aacObjectType=LOW; m_pfaacconf->shortctl=SHORTCTL_NORMAL; m_pfaacconf->quantqual=100; m_pfaacconf->bandWidth=0; m_pfaacconf->bitRate=0; faacEncSetConfiguration(m_hfaac,m_pfaacconf); faacEncGetDecoderSpecificInfo(m_hfaac,&m_pfaacinfobuffer,&m_nfaacinfosize); } return 0; }
int aacEncoder::init() { hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes); assert(hEncoder != NULL); pConfiguration = faacEncGetCurrentConfiguration(hEncoder); pConfiguration->allowMidside = 1; pConfiguration->inputFormat = FAAC_INPUT_16BIT; pConfiguration->aacObjectType = LOW; pConfiguration->mpegVersion = MPEG4; pConfiguration->useTns = true; pConfiguration->useLfe = true; pConfiguration->outputFormat = 0; pConfiguration->quantqual = 100; pConfiguration->bandWidth = 80*200; pConfiguration->shortctl = SHORTCTL_NORMAL; faacEncSetConfiguration(hEncoder, pConfiguration); LOGI("nSampleRate = %ld, nChannels = %u, nInputSamples = %ld, nMaxOutputBytes = %ld", nSampleRate, nChannels, nInputSamples, nMaxOutputBytes); faacEncGetDecoderSpecificInfo(hEncoder, &audioInfo, &audioInfoLen); interrupt = 0; return nInputSamples; }
int main(int argc, char *argv[]) { int frames, currentFrame; faacEncHandle hEncoder; pcmfile_t *infile = NULL; unsigned long samplesInput, maxBytesOutput, totalBytesWritten=0; faacEncConfigurationPtr myFormat; unsigned int mpegVersion = MPEG2; unsigned int objectType = LOW; unsigned int useMidSide = 1; static unsigned int useTns = DEFAULT_TNS; enum container_format container = NO_CONTAINER; int optimizeFlag = 0; enum stream_format stream = ADTS_STREAM; int cutOff = -1; int bitRate = 0; unsigned long quantqual = 0; int chanC = 3; int chanLF = 4; char *audioFileName = NULL; char *aacFileName = NULL; char *aacFileExt = NULL; int aacFileNameGiven = 0; float *pcmbuf; int *chanmap = NULL; unsigned char *bitbuf; int samplesRead = 0; const char *dieMessage = NULL; int rawChans = 0; // disabled by default int rawBits = 16; int rawRate = 44100; int rawEndian = 1; int shortctl = SHORTCTL_NORMAL; FILE *outfile = NULL; #ifdef HAVE_LIBMP4V2 MP4FileHandle MP4hFile = MP4_INVALID_FILE_HANDLE; MP4TrackId MP4track = 0; unsigned int ntracks = 0, trackno = 0; unsigned int ndiscs = 0, discno = 0; u_int8_t compilation = 0; const char *artist = NULL, *title = NULL, *album = NULL, *year = NULL, *genre = NULL, *comment = NULL, *writer = NULL; u_int8_t *art = NULL; u_int64_t artSize = 0; u_int64_t total_samples = 0; u_int64_t encoded_samples = 0; unsigned int delay_samples; unsigned int frameSize; #endif char *faac_id_string; char *faac_copyright_string; #ifndef _WIN32 // install signal handler signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); #endif // get faac version if (faacEncGetVersion(&faac_id_string, &faac_copyright_string) == FAAC_CFG_VERSION) { fprintf(stderr, "Freeware Advanced Audio Coder\nFAAC %s\n\n", faac_id_string); } else { fprintf(stderr, __FILE__ "(%d): wrong libfaac version\n", __LINE__); return 1; } /* begin process command line */ progName = argv[0]; while (1) { static struct option long_options[] = { { "help", 0, 0, 'h'}, { "long-help", 0, 0, 'H'}, { "raw", 0, 0, 'r'}, { "no-midside", 0, 0, NO_MIDSIDE_FLAG}, { "cutoff", 1, 0, 'c'}, { "quality", 1, 0, 'q'}, { "pcmraw", 0, 0, 'P'}, { "pcmsamplerate", 1, 0, 'R'}, { "pcmsamplebits", 1, 0, 'B'}, { "pcmchannels", 1, 0, 'C'}, { "shortctl", 1, 0, SHORTCTL_FLAG}, { "tns", 0, 0, TNS_FLAG}, { "no-tns", 0, 0, NO_TNS_FLAG}, { "mpeg-version", 1, 0, MPEGVERS_FLAG}, { "obj-type", 1, 0, OBJTYPE_FLAG}, { "license", 0, 0, 'L'}, #ifdef HAVE_LIBMP4V2 { "createmp4", 0, 0, 'w'}, { "optimize", 0, 0, 's'}, { "artist", 1, 0, ARTIST_FLAG}, { "title", 1, 0, TITLE_FLAG}, { "album", 1, 0, ALBUM_FLAG}, { "track", 1, 0, TRACK_FLAG}, { "disc", 1, 0, DISC_FLAG}, { "genre", 1, 0, GENRE_FLAG}, { "year", 1, 0, YEAR_FLAG}, { "cover-art", 1, 0, COVER_ART_FLAG}, { "comment", 1, 0, COMMENT_FLAG}, { "writer", 1, 0, WRITER_FLAG}, { "compilation", 0, 0, COMPILATION_FLAG}, #endif { "pcmswapbytes", 0, 0, 'X'}, { 0, 0, 0, 0} }; int c = -1; int option_index = 0; c = getopt_long(argc, argv, "Hhb:m:o:rnc:q:PR:B:C:I:X" #ifdef HAVE_LIBMP4V2 "ws" #endif ,long_options, &option_index); if (c == -1) break; if (!c) { dieMessage = usage; break; } switch (c) { case 'o': { int l = strlen(optarg); aacFileName = malloc(l+1); memcpy(aacFileName, optarg, l); aacFileName[l] = '\0'; aacFileNameGiven = 1; } break; case 'r': { stream = RAW_STREAM; break; } case NO_MIDSIDE_FLAG: { useMidSide = 0; break; } case 'c': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { cutOff = i; } break; } case 'b': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { bitRate = 1000 * i; } break; } case 'q': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { if (i > 0 && i < 1000) quantqual = i; } break; } case 'I': sscanf(optarg, "%d,%d", &chanC, &chanLF); break; case 'P': rawChans = 2; // enable raw input break; case 'R': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { rawRate = i; rawChans = (rawChans > 0) ? rawChans : 2; } break; } case 'B': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) { if (i > 32) i = 32; if (i < 8) i = 8; rawBits = i; rawChans = (rawChans > 0) ? rawChans : 2; } break; } case 'C': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) rawChans = i; break; } #ifdef HAVE_LIBMP4V2 case 'w': container = MP4_CONTAINER; break; case 's': optimizeFlag = 1; break; case ARTIST_FLAG: artist = optarg; break; case WRITER_FLAG: writer = optarg; break; case TITLE_FLAG: title = optarg; break; case ALBUM_FLAG: album = optarg; break; case TRACK_FLAG: sscanf(optarg, "%d/%d", &trackno, &ntracks); break; case DISC_FLAG: sscanf(optarg, "%d/%d", &discno, &ndiscs); break; case COMPILATION_FLAG: compilation = 0x1; break; case GENRE_FLAG: genre = optarg; break; case YEAR_FLAG: year = optarg; break; case COMMENT_FLAG: comment = optarg; break; case COVER_ART_FLAG: { FILE *artFile = fopen(optarg, "rb"); if(artFile) { u_int64_t r; fseek(artFile, 0, SEEK_END); artSize = ftell(artFile); art = malloc(artSize); fseek(artFile, 0, SEEK_SET); clearerr(artFile); r = fread(art, artSize, 1, artFile); if (r != 1) { dieMessage = "Error reading cover art file!\n"; free(art); art = NULL; } else if (artSize < 12 || !check_image_header(art)) { /* the above expression checks the image signature */ dieMessage = "Unsupported cover image file format!\n"; free(art); art = NULL; } fclose(artFile); } else { dieMessage = "Error opening cover art file!\n"; } break; } #endif case SHORTCTL_FLAG: shortctl = atoi(optarg); break; case TNS_FLAG: useTns = 1; break; case NO_TNS_FLAG: useTns = 0; break; case MPEGVERS_FLAG: mpegVersion = atoi(optarg); switch(mpegVersion) { case 2: mpegVersion = MPEG2; break; case 4: mpegVersion = MPEG4; break; default: dieMessage = "Unrecognised MPEG version!\n"; } break; #if 0 case OBJTYPE_FLAG: if (!strcasecmp(optarg, "LC")) objectType = LOW; else if (!strcasecmp(optarg, "Main")) objectType = MAIN; else if (!strcasecmp(optarg, "LTP")) { mpegVersion = MPEG4; objectType = LTP; } else dieMessage = "Unrecognised object type!\n"; break; #endif case 'L': fprintf(stderr, faac_copyright_string); dieMessage = license; break; case 'X': rawEndian = 0; break; case 'H': dieMessage = long_help; break; case 'h': dieMessage = short_help; break; case '?': default: dieMessage = usage; break; } } /* check that we have at least one non-option arguments */ if (!dieMessage && (argc - optind) > 1 && aacFileNameGiven) dieMessage = "Cannot encode several input files to one output file.\n"; if (argc - optind < 1 || dieMessage) { fprintf(stderr, dieMessage ? dieMessage : usage, progName, progName, progName, progName); return 1; } while (argc - optind > 0) { /* get the input file name */ audioFileName = argv[optind++]; /* generate the output file name, if necessary */ if (!aacFileNameGiven) { char *t = strrchr(audioFileName, '.'); int l = t ? strlen(audioFileName) - strlen(t) : strlen(audioFileName); #ifdef HAVE_LIBMP4V2 aacFileExt = container == MP4_CONTAINER ? ".m4a" : ".aac"; #else aacFileExt = ".aac"; #endif aacFileName = malloc(l+1+4); memcpy(aacFileName, audioFileName, l); memcpy(aacFileName + l, aacFileExt, 4); aacFileName[l+4] = '\0'; } else { aacFileExt = strrchr(aacFileName, '.'); if (aacFileExt && (!strcmp(".m4a", aacFileExt) || !strcmp(".m4b", aacFileExt) || !strcmp(".mp4", aacFileExt))) #ifndef HAVE_LIBMP4V2 fprintf(stderr, "WARNING: MP4 support unavailable!\n"); #else container = MP4_CONTAINER; #endif } /* open the audio input file */ if (rawChans > 0) // use raw input { infile = wav_open_read(audioFileName, 1); if (infile) { infile->bigendian = rawEndian; infile->channels = rawChans; infile->samplebytes = rawBits / 8; infile->samplerate = rawRate; infile->samples /= (infile->channels * infile->samplebytes); } } else // header input infile = wav_open_read(audioFileName, 0); if (infile == NULL) { fprintf(stderr, "Couldn't open input file %s\n", audioFileName); return 1; } /* open the encoder library */ hEncoder = faacEncOpen(infile->samplerate, infile->channels, &samplesInput, &maxBytesOutput); #ifdef HAVE_LIBMP4V2 if (container != MP4_CONTAINER && (ntracks || trackno || artist || title || album || year || art || genre || comment || discno || ndiscs || writer || compilation)) { fprintf(stderr, "Metadata requires MP4 output!\n"); return 1; } if (container == MP4_CONTAINER) { mpegVersion = MPEG4; stream = RAW_STREAM; } frameSize = samplesInput/infile->channels; delay_samples = frameSize; // encoder delay 1024 samples #endif pcmbuf = (float *)malloc(samplesInput*sizeof(float)); bitbuf = (unsigned char*)malloc(maxBytesOutput*sizeof(unsigned char)); chanmap = mkChanMap(infile->channels, chanC, chanLF); if (chanmap) { fprintf(stderr, "Remapping input channels: Center=%d, LFE=%d\n", chanC, chanLF); } if (cutOff <= 0) { if (cutOff < 0) // default cutOff = 0; else // disabled cutOff = infile->samplerate / 2; } if (cutOff > (infile->samplerate / 2)) cutOff = infile->samplerate / 2; /* put the options in the configuration struct */ myFormat = faacEncGetCurrentConfiguration(hEncoder); myFormat->aacObjectType = objectType; myFormat->mpegVersion = mpegVersion; myFormat->useTns = useTns; switch (shortctl) { case SHORTCTL_NOSHORT: fprintf(stderr, "disabling short blocks\n"); myFormat->shortctl = shortctl; break; case SHORTCTL_NOLONG: fprintf(stderr, "disabling long blocks\n"); myFormat->shortctl = shortctl; break; } if (infile->channels >= 6) myFormat->useLfe = 1; myFormat->allowMidside = useMidSide; if (bitRate) myFormat->bitRate = bitRate / infile->channels; myFormat->bandWidth = cutOff; if (quantqual > 0) myFormat->quantqual = quantqual; myFormat->outputFormat = stream; myFormat->inputFormat = FAAC_INPUT_FLOAT; if (!faacEncSetConfiguration(hEncoder, myFormat)) { fprintf(stderr, "Unsupported output format!\n"); #ifdef HAVE_LIBMP4V2 if (container == MP4_CONTAINER) MP4Close(MP4hFile); #endif return 1; } #ifdef HAVE_LIBMP4V2 /* initialize MP4 creation */ if (container == MP4_CONTAINER) { unsigned char *ASC = 0; unsigned long ASCLength = 0; char *version_string; #ifdef MP4_CREATE_EXTENSIBLE_FORMAT /* hack to compile against libmp4v2 >= 1.0RC3 * why is there no version identifier in mp4.h? */ MP4hFile = MP4Create(aacFileName, MP4_DETAILS_ERROR, 0); #else MP4hFile = MP4Create(aacFileName, MP4_DETAILS_ERROR, 0, 0); #endif if (!MP4_IS_VALID_FILE_HANDLE(MP4hFile)) { fprintf(stderr, "Couldn't create output file %s\n", aacFileName); return 1; } MP4SetTimeScale(MP4hFile, 90000); MP4track = MP4AddAudioTrack(MP4hFile, infile->samplerate, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE); MP4SetAudioProfileLevel(MP4hFile, 0x0F); faacEncGetDecoderSpecificInfo(hEncoder, &ASC, &ASCLength); MP4SetTrackESConfiguration(MP4hFile, MP4track, ASC, ASCLength); free(ASC); /* set metadata */ version_string = malloc(strlen(faac_id_string) + 6); strcpy(version_string, "FAAC "); strcpy(version_string + 5, faac_id_string); MP4SetMetadataTool(MP4hFile, version_string); free(version_string); if (artist) MP4SetMetadataArtist(MP4hFile, artist); if (writer) MP4SetMetadataWriter(MP4hFile, writer); if (title) MP4SetMetadataName(MP4hFile, title); if (album) MP4SetMetadataAlbum(MP4hFile, album); if (trackno > 0) MP4SetMetadataTrack(MP4hFile, trackno, ntracks); if (discno > 0) MP4SetMetadataDisk(MP4hFile, discno, ndiscs); if (compilation) MP4SetMetadataCompilation(MP4hFile, compilation); if (year) MP4SetMetadataYear(MP4hFile, year); if (genre) MP4SetMetadataGenre(MP4hFile, genre); if (comment) MP4SetMetadataComment(MP4hFile, comment); if (artSize) { MP4SetMetadataCoverArt(MP4hFile, art, artSize); free(art); } } else { #endif /* open the aac output file */ if (!strcmp(aacFileName, "-")) { outfile = stdout; } else { outfile = fopen(aacFileName, "wb"); } if (!outfile) { fprintf(stderr, "Couldn't create output file %s\n", aacFileName); return 1; } #ifdef HAVE_LIBMP4V2 } #endif cutOff = myFormat->bandWidth; quantqual = myFormat->quantqual; bitRate = myFormat->bitRate; if (bitRate) fprintf(stderr, "Average bitrate: %d kbps\n", (bitRate + 500)/1000*infile->channels); fprintf(stderr, "Quantization quality: %ld\n", quantqual); fprintf(stderr, "Bandwidth: %d Hz\n", cutOff); fprintf(stderr, "Object type: "); switch(objectType) { case LOW: fprintf(stderr, "Low Complexity"); break; case MAIN: fprintf(stderr, "Main"); break; case LTP: fprintf(stderr, "LTP"); break; } fprintf(stderr, "(MPEG-%d)", (mpegVersion == MPEG4) ? 4 : 2); if (myFormat->useTns) fprintf(stderr, " + TNS"); if (myFormat->allowMidside) fprintf(stderr, " + M/S"); fprintf(stderr, "\n"); fprintf(stderr, "Container format: "); switch(container) { case NO_CONTAINER: switch(stream) { case RAW_STREAM: fprintf(stderr, "Headerless AAC (RAW)\n"); break; case ADTS_STREAM: fprintf(stderr, "Transport Stream (ADTS)\n"); break; } break; #ifdef HAVE_LIBMP4V2 case MP4_CONTAINER: fprintf(stderr, "MPEG-4 File Format (MP4)\n"); break; #endif } if (outfile #ifdef HAVE_LIBMP4V2 || MP4hFile != MP4_INVALID_FILE_HANDLE #endif ) { int showcnt = 0; #ifdef _WIN32 long begin = GetTickCount(); #endif if (infile->samples) frames = ((infile->samples + 1023) / 1024) + 1; else frames = 0; currentFrame = 0; fprintf(stderr, "Encoding %s to %s\n", audioFileName, aacFileName); if (frames != 0) fprintf(stderr, " frame | bitrate | elapsed/estim | " "play/CPU | ETA\n"); else fprintf(stderr, " frame | elapsed | play/CPU\n"); /* encoding loop */ #ifdef _WIN32 for (;;) #else while (running) #endif { int bytesWritten; samplesRead = wav_read_float32(infile, pcmbuf, samplesInput, chanmap); #ifdef HAVE_LIBMP4V2 total_samples += samplesRead / infile->channels; #endif /* call the actual encoding routine */ bytesWritten = faacEncEncode(hEncoder, (int32_t *)pcmbuf, samplesRead, bitbuf, maxBytesOutput); if (bytesWritten) { currentFrame++; showcnt--; totalBytesWritten += bytesWritten; } if ((showcnt <= 0) || !bytesWritten) { double timeused; #ifdef __unix__ struct rusage usage; #endif #ifdef _WIN32 char percent[MAX_PATH + 20]; timeused = (GetTickCount() - begin) * 1e-3; #else #ifdef __unix__ if (getrusage(RUSAGE_SELF, &usage) == 0) { timeused = (double)usage.ru_utime.tv_sec + (double)usage.ru_utime.tv_usec * 1e-6; } else timeused = 0; #else timeused = (double)clock() * (1.0 / CLOCKS_PER_SEC); #endif #endif if (currentFrame && (timeused > 0.1)) { showcnt += 50; if (frames != 0) fprintf(stderr, "\r%5d/%-5d (%3d%%)| %5.1f | %6.1f/%-6.1f | %7.2fx | %.1f ", currentFrame, frames, currentFrame*100/frames, ((double)totalBytesWritten * 8.0 / 1000.0) / ((double)infile->samples / infile->samplerate * currentFrame / frames), timeused, timeused * frames / currentFrame, (1024.0 * currentFrame / infile->samplerate) / timeused, timeused * (frames - currentFrame) / currentFrame); else fprintf(stderr, "\r %5d | %6.1f | %7.2fx ", currentFrame, timeused, (1024.0 * currentFrame / infile->samplerate) / timeused); fflush(stderr); #ifdef _WIN32 if (frames != 0) { sprintf(percent, "%.2f%% encoding %s", 100.0 * currentFrame / frames, audioFileName); SetConsoleTitle(percent); } #endif } } /* all done, bail out */ if (!samplesRead && !bytesWritten) break ; if (bytesWritten < 0) { fprintf(stderr, "faacEncEncode() failed\n"); break ; } if (bytesWritten > 0) { #ifdef HAVE_LIBMP4V2 u_int64_t samples_left = total_samples - encoded_samples + delay_samples; MP4Duration dur = samples_left > frameSize ? frameSize : samples_left; MP4Duration ofs = encoded_samples > 0 ? 0 : delay_samples; if (container == MP4_CONTAINER) { /* write bitstream to mp4 file */ MP4WriteSample(MP4hFile, MP4track, bitbuf, bytesWritten, dur, ofs, 1); } else { #endif /* write bitstream to aac file */ fwrite(bitbuf, 1, bytesWritten, outfile); #ifdef HAVE_LIBMP4V2 } encoded_samples += dur; #endif } } #ifdef HAVE_LIBMP4V2 /* clean up */ if (container == MP4_CONTAINER) { MP4Close(MP4hFile); if (optimizeFlag == 1) { fprintf(stderr, "\n\nMP4 format optimization... "); MP4Optimize(aacFileName, NULL, 0); fprintf(stderr, "Done!"); } } else #endif fclose(outfile); fprintf(stderr, "\n\n"); } faacEncClose(hEncoder); wav_close(infile); if (pcmbuf) free(pcmbuf); if (bitbuf) free(bitbuf); if (aacFileNameGiven) free(aacFileName); } return 0; }
static av_cold int Faac_encode_init(AVCodecContext *avctx) { FaacAudioContext *s = avctx->priv_data; faacEncConfigurationPtr faac_cfg; unsigned long samples_input, max_bytes_output; int ret; /* number of channels */ if (avctx->channels < 1 || avctx->channels > 6) { av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); ret = AVERROR(EINVAL); goto error; } s->faac_handle = faacEncOpen(avctx->sample_rate, avctx->channels, &samples_input, &max_bytes_output); if (!s->faac_handle) { av_log(avctx, AV_LOG_ERROR, "error in faacEncOpen()\n"); ret = AVERROR_UNKNOWN; goto error; } /* check faac version */ faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle); if (faac_cfg->version != FAAC_CFG_VERSION) { av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version); ret = AVERROR(EINVAL); goto error; } /* put the options in the configuration struct */ switch(avctx->profile) { case FF_PROFILE_AAC_MAIN: faac_cfg->aacObjectType = MAIN; break; case FF_PROFILE_UNKNOWN: case FF_PROFILE_AAC_LOW: faac_cfg->aacObjectType = LOW; break; case FF_PROFILE_AAC_SSR: faac_cfg->aacObjectType = SSR; break; case FF_PROFILE_AAC_LTP: faac_cfg->aacObjectType = LTP; break; default: av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n"); ret = AVERROR(EINVAL); goto error; } faac_cfg->mpegVersion = MPEG4; faac_cfg->useTns = 0; faac_cfg->allowMidside = 1; faac_cfg->bitRate = avctx->bit_rate / avctx->channels; faac_cfg->bandWidth = avctx->cutoff; if(avctx->flags & CODEC_FLAG_QSCALE) { faac_cfg->bitRate = 0; faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA; } faac_cfg->outputFormat = 1; faac_cfg->inputFormat = FAAC_INPUT_16BIT; if (avctx->channels > 2) memcpy(faac_cfg->channel_map, channel_maps[avctx->channels-3], avctx->channels * sizeof(int)); avctx->frame_size = samples_input / avctx->channels; #if FF_API_OLD_ENCODE_AUDIO avctx->coded_frame= avcodec_alloc_frame(); if (!avctx->coded_frame) { ret = AVERROR(ENOMEM); goto error; } #endif /* 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 (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer, &decoder_specific_info_size)) { avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!avctx->extradata) { ret = AVERROR(ENOMEM); goto error; } avctx->extradata_size = decoder_specific_info_size; memcpy(avctx->extradata, buffer, avctx->extradata_size); faac_cfg->outputFormat = 0; } free(buffer); } if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) { av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n"); ret = AVERROR(EINVAL); goto error; } avctx->delay = FAAC_DELAY_SAMPLES; ff_af_queue_init(avctx, &s->afq); return 0; error: Faac_encode_close(avctx); return ret; }
bool AudioEncoderFAAC::initialize() { if(encoder) { STREAMER_ERROR("It seems that you already initialized the AudioEncoderFAAC. I'm not initializing again. First shutdown()."); return false; } if(!validateSettings(settings)) { return false; } encoder = faacEncOpen(settings.samplerate, getNumChannels(), &nsamples_needed, &nbytes_out); if(!encoder) { STREAMER_ERROR("Error while trying to open the FAAC encoder.\n"); return false; } faac_buffer = new unsigned char[nbytes_out]; if(!faac_buffer) { STREAMER_ERROR("Erorr while allocating the buffer for the encoded faac data.\n"); shutdown(); return false; } STREAMER_STATUS("FAAC, nsamples_needed: %ld, nbytes_out: %ld\n", nsamples_needed, nbytes_out); // configure faac faacEncConfigurationPtr config = faacEncGetCurrentConfiguration(encoder); config->mpegVersion = MPEG4; config->aacObjectType = LOW; config->useLfe = 0; config->quantqual = 100; config->bitRate = settings.bitrate * 1000 / getNumChannels(); config->outputFormat = 0; // 0 = Raw, 1 = ADTS if(settings.in_bitsize == AV_AUDIO_BITSIZE_S16) { config->inputFormat = FAAC_INPUT_16BIT; } else if(settings.in_bitsize == AV_AUDIO_BITSIZE_F32) { config->inputFormat = FAAC_INPUT_FLOAT; } else { STREAMER_ERROR("Cannot initialize the AudioEncoderFAAC because the in_bitsize is invalid. we only support S16 of F32.\n"); ::exit(EXIT_FAILURE); } int r = faacEncSetConfiguration(encoder, config); if(!r) { STREAMER_ERROR("Error while setting the configuration for faac.\n"); shutdown(); return false; } // get the decoder specific config unsigned char* header; unsigned long header_size = 0; r = faacEncGetDecoderSpecificInfo(encoder, &header, &header_size); if(r < 0) { STREAMER_ERROR("Error while trying to get the decoder specific info from libfaac.\n"); shutdown(); return false; } std::copy(header, header + header_size, std::back_inserter(audio_specific_config)); free(header); header = NULL; // write data to file if output file has been specified if(output_file.size()) { ofs.open(output_file.c_str(), std::ios::out | std::ios::binary); if(!ofs.is_open()) { STREAMER_ERROR("Cannot open the output file for the AudioEncoderFAAC: %s\n", output_file.c_str()); ::exit(EXIT_FAILURE); } ofs.write((char*)header, header_size); } STREAMER_STATUS("Bitrate in bits per channel: %d, decoder size: %ld\n", config->bitRate, header_size); return true; }
int mpae_init_faac(audio_encoder_t *encoder) { if(encoder->params.channels < 1 || encoder->params.channels > 6 || (param_mpeg != 2 && param_mpeg != 4)) { mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, unsupported number of channels: %d, or mpeg version: %d, exit\n", encoder->params.channels, param_mpeg); return 0; } faac = faacEncOpen(encoder->params.sample_rate, encoder->params.channels, &samples_input, &max_bytes_output); if(!faac) { mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't init, exit\n"); return 0; } mp_msg(MSGT_MENCODER, MSGL_V, "AE_FAAC, sample_input: %lu, max_bytes_output: %lu\n", samples_input, max_bytes_output); config = faacEncGetCurrentConfiguration(faac); if(!config) { mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't get init configuration, exit\n"); return 0; } param_bitrate *= 1000; if(param_quality) config->quantqual = param_quality; else config->bitRate = param_bitrate / encoder->params.channels; if(param_format==33) { config->inputFormat = FAAC_INPUT_FLOAT; divisor = 4; } else if(param_format==32) { config->inputFormat = FAAC_INPUT_32BIT; divisor = 4; } else { config->inputFormat = FAAC_INPUT_16BIT; divisor = 2; } config->outputFormat = param_raw ? 0 : 1; // 1 is ADTS config->aacObjectType = param_object_type; if(MAIN==0) config->aacObjectType--; config->mpegVersion = (param_mpeg == 4 ? MPEG4 : MPEG2); config->useTns = param_tns; config->allowMidside = 1; config->shortctl = SHORTCTL_NORMAL; param_cutoff = param_cutoff ? param_cutoff : encoder->params.sample_rate / 2; if(param_cutoff > encoder->params.sample_rate / 2) param_cutoff = encoder->params.sample_rate / 2; config->bandWidth = param_cutoff; if(encoder->params.channels == 6) config->useLfe = 1; if(!faacEncSetConfiguration(faac, config)) { mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, counldn't set specified parameters, exiting\n"); return 0; } if(param_raw) faacEncGetDecoderSpecificInfo(faac, &decoder_specific_buffer, &decoder_specific_len); else decoder_specific_len = 0; encoder->params.bitrate = param_bitrate; encoder->params.samples_per_frame = 1024; encoder->decode_buffer_size = divisor * samples_input; //samples * 16 bits_per_sample encoder->bind = bind_faac; encoder->get_frame_size = get_frame_size; encoder->encode = encode_faac; encoder->close = close_faac; return 1; }
static av_cold int Faac_encode_init(AVCodecContext *avctx) { FaacAudioContext *s = avctx->priv_data; faacEncConfigurationPtr faac_cfg; unsigned long samples_input, max_bytes_output; /* number of channels */ if (avctx->channels < 1 || avctx->channels > 6) return -1; s->faac_handle = faacEncOpen(avctx->sample_rate, avctx->channels, &samples_input, &max_bytes_output); /* check faac version */ faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle); if (faac_cfg->version != FAAC_CFG_VERSION) { av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version); faacEncClose(s->faac_handle); return -1; } /* put the options in the configuration struct */ switch(avctx->profile) { case FF_PROFILE_AAC_MAIN: faac_cfg->aacObjectType = MAIN; break; case FF_PROFILE_UNKNOWN: case FF_PROFILE_AAC_LOW: faac_cfg->aacObjectType = LOW; break; case FF_PROFILE_AAC_SSR: faac_cfg->aacObjectType = SSR; break; case FF_PROFILE_AAC_LTP: faac_cfg->aacObjectType = LTP; break; default: av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n"); faacEncClose(s->faac_handle); return -1; } faac_cfg->mpegVersion = MPEG4; faac_cfg->useTns = 0; faac_cfg->allowMidside = 1; faac_cfg->bitRate = avctx->bit_rate / avctx->channels; faac_cfg->bandWidth = avctx->cutoff; if(avctx->flags & CODEC_FLAG_QSCALE) { faac_cfg->bitRate = 0; faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA; } faac_cfg->outputFormat = 1; faac_cfg->inputFormat = FAAC_INPUT_16BIT; 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 (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer, &decoder_specific_info_size)) { 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); faac_cfg->outputFormat = 0; } #undef free free(buffer); #define free please_use_av_free } if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) { av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n"); return -1; } return 0; }
/*********************************************************************** * hb_work_encfaac_init *********************************************************************** * **********************************************************************/ int encfaacInit( hb_work_object_t * w, hb_job_t * job ) { hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) ); hb_audio_t * audio = w->audio; faacEncConfigurationPtr cfg; uint8_t * bytes; unsigned long length; w->private_data = pv; pv->job = job; /* pass the number of channels used into the private work data */ pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown); pv->faac = faacEncOpen( audio->config.out.samplerate, pv->out_discrete_channels, &pv->input_samples, &pv->output_bytes ); pv->buf = malloc( pv->input_samples * sizeof( float ) ); pv->obuf = malloc( pv->output_bytes ); pv->framedur = 90000.0 * pv->input_samples / ( audio->config.out.samplerate * pv->out_discrete_channels ); audio->config.out.samples_per_frame = pv->input_samples / pv->out_discrete_channels; cfg = faacEncGetCurrentConfiguration( pv->faac ); cfg->mpegVersion = MPEG4; cfg->aacObjectType = LOW; cfg->allowMidside = 1; /* channel configuration & remapping */ uint64_t layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL); hb_audio_remap_build_table(&hb_aac_chan_map, audio->config.in.channel_map, layout, cfg->channel_map); switch (audio->config.out.mixdown) { case HB_AMIXDOWN_7POINT1: cfg->channelConfiguration = 0; cfg->numFrontChannels = 3; cfg->numSideChannels = 2; cfg->numBackChannels = 2; cfg->numLFEChannels = 1; break; case HB_AMIXDOWN_6POINT1: cfg->channelConfiguration = 0; cfg->numFrontChannels = 3; cfg->numSideChannels = 0; cfg->numBackChannels = 3; cfg->numLFEChannels = 1; break; case HB_AMIXDOWN_5_2_LFE: cfg->channelConfiguration = 7; break; default: cfg->channelConfiguration = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown); break; } cfg->useTns = 0; cfg->bitRate = audio->config.out.bitrate * 1000 / pv->out_discrete_channels; /* Per channel */ cfg->bandWidth = 0; cfg->outputFormat = 0; cfg->inputFormat = FAAC_INPUT_FLOAT; if( !faacEncSetConfiguration( pv->faac, cfg ) ) { hb_log( "faacEncSetConfiguration failed" ); *job->done_error = HB_ERROR_INIT; *job->die = 1; return 0; } if( faacEncGetDecoderSpecificInfo( pv->faac, &bytes, &length ) < 0 ) { hb_log( "faacEncGetDecoderSpecificInfo failed" ); *job->done_error = HB_ERROR_INIT; *job->die = 1; return 0; } memcpy( w->config->extradata.bytes, bytes, length ); w->config->extradata.length = length; free( bytes ); pv->list = hb_list_init(); return 0; }
//________________________________________________ // Init lame encoder // frequence : Impose frequency , 0 means reuse the incoming fq // mode : ADM_STEREO etc... // bitrate : Bitrate in kbps (96,192...) // return 0 : init failed // 1 : init succeeded //_______________________________________________ uint8_t AUDMEncoder_Faac::init(ADM_audioEncoderDescriptor *config) { unsigned long int samples_input, max_bytes_output; faacEncConfigurationPtr cfg; int ret=0; printf("[FAAC] Incoming Fq :%u\n",_wavheader->frequency); _handle = faacEncOpen(_wavheader->frequency, _wavheader->channels, &samples_input, &max_bytes_output); if(!_handle) { printf("Cannot open faac with fq=%lu chan=%lu br=%lu\n", _wavheader->frequency,_wavheader->channels,config->bitrate); return 0; } printf(" [FAAC] : Sample input:%d, max byte output%d \n",samples_input,max_bytes_output); cfg= faacEncGetCurrentConfiguration(_handle); // Set default conf, same as ffmpeg cfg->aacObjectType = LOW; cfg->mpegVersion = MPEG4; cfg->bandWidth= (_wavheader->frequency*3)/4; // Should be relevant cfg->useTns = 0; cfg->allowMidside = 0; cfg->bitRate = (config->bitrate*1000)/_wavheader->channels; // It is per channel cfg->outputFormat = 0; // 0 Raw 1 ADTS cfg->inputFormat = FAAC_INPUT_FLOAT; cfg->useLfe=0; if (!(ret=faacEncSetConfiguration(_handle, cfg))) { printf("[FAAC] Cannot set conf for faac with fq=%lu chan=%lu br=%lu (err:%d)\n", _wavheader->frequency,_wavheader->channels,config->bitrate,ret); return 0; } unsigned char *data=NULL; unsigned long size=0; if((ret=faacEncGetDecoderSpecificInfo(_handle, &data,&size))) { printf("FAAC: GetDecoderSpecific info failed (err:%d)\n",ret); return 0; } _extraSize=size; _extraData=new uint8_t[size]; memcpy(_extraData,data,size); // update _wavheader->byterate=(config->bitrate*1000)/8; // _wavheader->dwScale=1024; // _wavheader->dwSampleSize=0; _wavheader->blockalign=4096; _wavheader->bitspersample=0; _chunk=samples_input; printf("[Faac] Initialized :\n"); printf("[Faac]Version : %s\n",cfg->name); printf("[Faac]Bitrate : %lu\n",cfg->bitRate); printf("[Faac]Mpeg2 (1)/4(0) : %u\n",cfg->mpegVersion); printf("[Faac]Use lfe ) : %u\n",cfg->useLfe); printf("[Faac]Sample output : %lu\n",_chunk / _wavheader->channels); printf("[Faac]Bitrate : %lu\n",cfg->bitRate*_wavheader->channels); return 1; }
/*********************************************************************** * hb_work_encfaac_init *********************************************************************** * **********************************************************************/ int encfaacInit( hb_work_object_t * w, hb_job_t * job ) { hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) ); hb_audio_t * audio = w->audio; faacEncConfigurationPtr cfg; uint8_t * bytes; unsigned long length; w->private_data = pv; pv->job = job; /* pass the number of channels used into the private work data */ pv->out_discrete_channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown); /* if the sample rate is 'auto' and that has given us an invalid output */ /* rate, map it to the next highest output rate or 48K if above the highest. */ int rate_index = find_samplerate(audio->config.out.samplerate); if ( audio->config.out.samplerate != valid_rates[rate_index] ) { int rate = valid_rates[valid_rates[rate_index]? rate_index : rate_index - 1]; hb_log( "encfaac changing output samplerate from %d to %d", audio->config.out.samplerate, rate ); audio->config.out.samplerate = rate; /* if the new rate is over the max bandwidth per channel limit */ /* lower the bandwidth. */ double bw = audio->config.out.bitrate * 1000 / pv->out_discrete_channels; if ( bw > (double)rate * (6144./1024.) ) { int newbr = (double)rate * (6.144/1024.) * pv->out_discrete_channels; hb_log( "encfaac changing output bitrate from %d to %d", audio->config.out.bitrate, newbr ); audio->config.out.bitrate = newbr; } } pv->faac = faacEncOpen( audio->config.out.samplerate, pv->out_discrete_channels, &pv->input_samples, &pv->output_bytes ); pv->buf = malloc( pv->input_samples * sizeof( float ) ); pv->obuf = malloc( pv->output_bytes ); pv->framedur = 90000.0 * pv->input_samples / ( audio->config.out.samplerate * pv->out_discrete_channels ); audio->config.out.samples_per_frame = pv->input_samples / pv->out_discrete_channels; cfg = faacEncGetCurrentConfiguration( pv->faac ); cfg->mpegVersion = MPEG4; cfg->aacObjectType = LOW; cfg->allowMidside = 1; if (pv->out_discrete_channels == 6) { /* we are preserving 5.1 audio into 6-channel AAC, so indicate that we have an lfe channel */ cfg->useLfe = 1; } else { cfg->useLfe = 0; } cfg->useTns = 0; cfg->bitRate = audio->config.out.bitrate * 1000 / pv->out_discrete_channels; /* Per channel */ cfg->bandWidth = 0; cfg->outputFormat = 0; cfg->inputFormat = FAAC_INPUT_FLOAT; if( ( audio->config.out.mixdown == HB_AMIXDOWN_6CH ) && ( audio->config.in.channel_map != &hb_qt_chan_map ) ) { if( audio->config.in.channel_map == &hb_ac3_chan_map ) { cfg->channel_map[0] = 2; cfg->channel_map[1] = 1; cfg->channel_map[2] = 3; cfg->channel_map[3] = 4; cfg->channel_map[4] = 5; cfg->channel_map[5] = 0; } else if( audio->config.in.channel_map == &hb_smpte_chan_map ) { cfg->channel_map[0] = 2; cfg->channel_map[1] = 0; cfg->channel_map[2] = 1; cfg->channel_map[3] = 4; cfg->channel_map[4] = 5; cfg->channel_map[5] = 3; } } if( !faacEncSetConfiguration( pv->faac, cfg ) ) { hb_log( "faacEncSetConfiguration failed" ); *job->die = 1; return 0; } if( faacEncGetDecoderSpecificInfo( pv->faac, &bytes, &length ) < 0 ) { hb_log( "faacEncGetDecoderSpecificInfo failed" ); *job->die = 1; return 0; } memcpy( w->config->extradata.bytes, bytes, length ); w->config->extradata.length = length; free( bytes ); pv->list = hb_list_init(); return 0; }
static int Faac_encode_init(AVCodecContext *avctx) { FaacAudioContext *s = avctx->priv_data; faacEncConfigurationPtr faac_cfg; unsigned long samples_input, max_bytes_output; /* number of channels */ if (avctx->channels < 1 || avctx->channels > 6) return -1; s->faac_handle = faacEncOpen(avctx->sample_rate, avctx->channels, &samples_input, &max_bytes_output); /* check faac version */ faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle); if (faac_cfg->version != FAAC_CFG_VERSION) { av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version); faacEncClose(s->faac_handle); return -1; } /* put the options in the configuration struct */ faac_cfg->aacObjectType = LOW; faac_cfg->mpegVersion = MPEG4; faac_cfg->useTns = 0; faac_cfg->allowMidside = 1; faac_cfg->bitRate = avctx->bit_rate / avctx->channels; if(avctx->flags & CODEC_FLAG_QSCALE) { faac_cfg->bitRate = 0; faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA; } faac_cfg->outputFormat = 0; faac_cfg->inputFormat = FAAC_INPUT_16BIT; if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) { av_log(avctx, AV_LOG_ERROR, "libfaac 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; unsigned long decoder_specific_info_size; if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer, &decoder_specific_info_size)) { avctx->extradata = buffer; avctx->extradata_size = decoder_specific_info_size; } } return 0; }
bool BleAudioEncoder_AAC::init(int samplerate, int channel, int bitrate) { if (channel < 1 || channel > 6) return false; m_samplerate = samplerate; m_channels = channel; m_bitrate = bitrate; faacEncConfigurationPtr aacConfig; m_faacHandle = faacEncOpen(m_samplerate, m_channels, &m_samplesInputSize, &m_maxOutputSize); // check faac version aacConfig = faacEncGetCurrentConfiguration(m_faacHandle); if (aacConfig->version != FAAC_CFG_VERSION) { faacEncClose(m_faacHandle); log_error("faacEncGetCurrentConfiguration failed"); return false; } // reserve reuseable output buffer m_outputBuffer = new unsigned char[m_maxOutputSize]; // put the options in the configuration struct. aacConfig->aacObjectType = LOW; // MAIN aacConfig->mpegVersion = MPEG4; aacConfig->useTns = 1; aacConfig->useLfe = 1; aacConfig->allowMidside = 1; aacConfig->bitRate = m_bitrate / channel; aacConfig->bandWidth = 0; aacConfig->quantqual = 100; aacConfig->outputFormat = 0; aacConfig->inputFormat = FAAC_INPUT_16BIT; aacConfig->shortctl = SHORTCTL_NORMAL; if (!faacEncSetConfiguration(m_faacHandle, aacConfig)) { log_error("faacEncSetConfiguration failed"); return false; } m_nFrameSize = m_samplesInputSize / channel; m_pInBuf = new int32_t[m_samplesInputSize]; // set decoder specific info unsigned long extradata_size = 0; unsigned char *buffer; unsigned long decoder_specific_info_size; if (!faacEncGetDecoderSpecificInfo(m_faacHandle, &buffer, &decoder_specific_info_size)) { extradata_size = decoder_specific_info_size; } log_trace("aac encoder extradata_size=%d", extradata_size); m_header.clear(); unsigned char af[2] = {0xaf, 0x00}; m_header.append((char *)af, 2); m_header.append((char*)buffer, extradata_size); BleFreeArray(buffer); return true; }
/*********************************************************************** * hb_work_encfaac_init *********************************************************************** * **********************************************************************/ int encfaacInit( hb_work_object_t * w, hb_job_t * job ) { hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) ); hb_audio_t * audio = w->audio; faacEncConfigurationPtr cfg; uint8_t * bytes; unsigned long length; w->private_data = pv; pv->job = job; /* pass the number of channels used into the private work data */ pv->out_discrete_channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown); /* if the sample rate is 'auto' and that has given us an invalid output */ /* rate, map it to the next highest output rate or 48K if above the highest. */ int rate_index = find_samplerate(audio->config.out.samplerate); if ( audio->config.out.samplerate != valid_rates[rate_index] ) { int rate = valid_rates[valid_rates[rate_index]? rate_index : rate_index - 1]; hb_log( "encfaac changing output samplerate from %d to %d", audio->config.out.samplerate, rate ); audio->config.out.samplerate = rate; /* if the new rate is over the max bandwidth per channel limit */ /* lower the bandwidth. */ double bw = audio->config.out.bitrate * 1000 / pv->out_discrete_channels; if ( bw > (double)rate * (6144./1024.) ) { int newbr = (double)rate * (6.144/1024.) * pv->out_discrete_channels; hb_log( "encfaac changing output bitrate from %d to %d", audio->config.out.bitrate, newbr ); audio->config.out.bitrate = newbr; } } pv->faac = faacEncOpen( audio->config.out.samplerate, pv->out_discrete_channels, &pv->input_samples, &pv->output_bytes ); pv->buf = malloc( pv->input_samples * sizeof( float ) ); pv->obuf = malloc( pv->output_bytes ); pv->framedur = 90000.0 * pv->input_samples / ( audio->config.out.samplerate * pv->out_discrete_channels ); audio->config.out.samples_per_frame = pv->input_samples / pv->out_discrete_channels; cfg = faacEncGetCurrentConfiguration( pv->faac ); cfg->mpegVersion = MPEG4; cfg->aacObjectType = LOW; cfg->allowMidside = 1; // channel remapping, LFE uint64_t layout; int *remap_table; layout = hb_ff_mixdown_xlat(audio->config.out.mixdown, NULL); remap_table = hb_audio_remap_build_table(layout, &hb_aac_chan_map, audio->config.in.channel_map); if (remap_table != NULL) { // faac does its own remapping memcpy(cfg->channel_map, remap_table, pv->out_discrete_channels * sizeof(int)); free(remap_table); } cfg->useLfe = !!(layout & AV_CH_LOW_FREQUENCY); cfg->useTns = 0; cfg->bitRate = audio->config.out.bitrate * 1000 / pv->out_discrete_channels; /* Per channel */ cfg->bandWidth = 0; cfg->outputFormat = 0; cfg->inputFormat = FAAC_INPUT_FLOAT; if( !faacEncSetConfiguration( pv->faac, cfg ) ) { hb_log( "faacEncSetConfiguration failed" ); *job->die = 1; return 0; } if( faacEncGetDecoderSpecificInfo( pv->faac, &bytes, &length ) < 0 ) { hb_log( "faacEncGetDecoderSpecificInfo failed" ); *job->die = 1; return 0; } memcpy( w->config->extradata.bytes, bytes, length ); w->config->extradata.length = length; free( bytes ); pv->list = hb_list_init(); return 0; }
int encoder_write(unsigned long id, void* rbuffer, unsigned long bsize) { int bytesencoded = 0; double *sbuffer = (double*) rbuffer; unsigned char *bbuffer = (unsigned char*) rbuffer; unsigned int framesize = 0; if(pestreams[id].firstwrite) { int v = 0; pestreams[id].enchandle = faacEncOpen(pestreams[id].cfrequency, pestreams[id].cchannels, &pestreams[id].samplesin, &pestreams[id].maxbytesout); pestreams[id].obuffer = (unsigned char*)sys_mem_alloc(pestreams[id].maxbytesout); pestreams[id].cachebuffer = (unsigned char*)sys_mem_alloc(pestreams[id].samplesin * 10); pestreams[id].fb_size = 0; pestreams[id].floatbuffer = 0; pestreams[id].econfig = faacEncGetCurrentConfiguration(pestreams[id].enchandle); pestreams[id].econfig->inputFormat = FAAC_INPUT_FLOAT; pestreams[id].econfig->aacObjectType = LOW; //objectType; if(pestreams[id].ismp4) { pestreams[id].econfig->mpegVersion = MPEG4; pestreams[id].econfig->outputFormat = 0; pestreams[id].econfig->allowMidside = 1; pestreams[id].econfig->shortctl = SHORTCTL_NORMAL; if(fsettings.plugin_settings_getnum("aac", "bitrate", &v, 0, 0))v = 0xa; pestreams[id].econfig->bitRate = (ibitrates[v] * 1000) / pestreams[id].cchannels; v = 0x2; if(fsettings.plugin_settings_getnum("aac", "quality", &v, 0, 0))v = 0x2; pestreams[id].econfig->quantqual = iqualities[v]; pestreams[id].econfig->bandWidth = pestreams[id].cfrequency / 2; }else{ pestreams[id].econfig->mpegVersion = MPEG2; pestreams[id].econfig->useTns = 0; pestreams[id].econfig->shortctl = SHORTCTL_NORMAL; pestreams[id].econfig->useLfe = 0; pestreams[id].econfig->allowMidside = 1; if(fsettings.plugin_settings_getnum("aac", "bitrate", &v, 0, 0))v = 0xa; pestreams[id].econfig->bitRate = (ibitrates[v] * 1000) / pestreams[id].cchannels; v = 0x2; if(fsettings.plugin_settings_getnum("aac", "quality", &v, 0, 0))v = 0x2; pestreams[id].econfig->quantqual = iqualities[v]; pestreams[id].econfig->bandWidth = 0; } faacEncSetConfiguration(pestreams[id].enchandle, pestreams[id].econfig); /* mp4 stuff */ if(pestreams[id].ismp4) { unsigned char *ASC = 0; unsigned long ASCLength = 0; char afname[v_sys_maxpath]; BOOL usedef = 1; WideCharToMultiByte(CP_ACP, 0, pestreams[id].filepath, -1, afname, sizeof(afname), "?", &usedef); # ifdef MP4_CREATE_EXTENSIBLE_FORMAT pestreams[id].mp4file = MP4Create(afname, 0, 0); # else pestreams[id].mp4file = MP4Create(afname, 0, 0, 0); # endif MP4SetTimeScale(pestreams[id].mp4file, 90000); pestreams[id].mp4track = MP4AddAudioTrack(pestreams[id].mp4file, pestreams[id].cfrequency, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE); MP4SetAudioProfileLevel(pestreams[id].mp4file, 0x0F); faacEncGetDecoderSpecificInfo(pestreams[id].enchandle, &ASC, &ASCLength); MP4SetTrackESConfiguration(pestreams[id].mp4file, pestreams[id].mp4track, ASC, ASCLength); free(ASC); MP4SetMetadataTool(pestreams[id].mp4file, "Fennec Player 1.1 (libfaac)"); } pestreams[id].totalsamples = 0; pestreams[id].encodedsamples = 0; pestreams[id].cachesize = 0; pestreams[id].firstwrite = 0; } /* if(pestreams[id].cbitspersample == 64) standard */ { unsigned int i = 0; unsigned int sbytes = pestreams[id].cbitspersample / 8; framesize = pestreams[id].samplesin / pestreams[id].cchannels; if(pestreams[id].ismp4) pestreams[id].totalsamples += bsize / sbytes; while(1) { if((int)(bsize / sbytes) - (int)i < (int)pestreams[id].samplesin) { if((int)(bsize / sbytes) - (int)i > 0) { memcpy(pestreams[id].cachebuffer + pestreams[id].cachesize, sbuffer + i, (bsize / sbytes) - i); pestreams[id].cachesize += (bsize / sbytes) - i; } break; } if(pestreams[id].cachesize) { memcpy(pestreams[id].cachebuffer + pestreams[id].cachesize, sbuffer + i, (pestreams[id].samplesin * sbytes) - pestreams[id].cachesize); local_write_doublebuffer(id, (double*)pestreams[id].cachebuffer, pestreams[id].samplesin, bytesencoded, framesize); pestreams[id].cachesize = 0; i += pestreams[id].samplesin - pestreams[id].cachesize; }else{ local_write_doublebuffer(id, (double*)(sbuffer + i), pestreams[id].samplesin, bytesencoded, framesize); i += pestreams[id].samplesin; } } } return 1; }