| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Interface to libfaac for aac encoding | 
					
						
							|  |  |  |  * Copyright (c) 2002 Gildas Bazin <gbazin@netcourrier.com> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * This file is part of FFmpeg. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FFmpeg is free software; you can redistribute it and/or | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * FFmpeg is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							| 
									
										
										
										
											2006-10-07 15:30:46 +00:00
										 |  |  |  * License along with FFmpeg; if not, write to the Free Software | 
					
						
							| 
									
										
										
										
											2006-01-12 22:43:26 +00:00
										 |  |  |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2005-12-17 18:14:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-04-20 14:45:34 +00:00
										 |  |  |  * @file | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |  * Interface to libfaac for aac encoding. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "avcodec.h"
 | 
					
						
							|  |  |  | #include <faac.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct FaacAudioContext { | 
					
						
							|  |  |  |     faacEncHandle faac_handle; | 
					
						
							|  |  |  | } FaacAudioContext; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-15 10:57:26 +02:00
										 |  |  | static const int channel_maps[][6] = { | 
					
						
							|  |  |  |     { 2, 0, 1 },          //< C L R
 | 
					
						
							|  |  |  |     { 2, 0, 1, 3 },       //< C L R Cs
 | 
					
						
							|  |  |  |     { 2, 0, 1, 3, 4 },    //< C L R Ls Rs
 | 
					
						
							|  |  |  |     { 2, 0, 1, 4, 5, 3 }, //< C L R Ls Rs LFE
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-21 03:11:20 +00:00
										 |  |  | static av_cold int Faac_encode_init(AVCodecContext *avctx) | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     FaacAudioContext *s = avctx->priv_data; | 
					
						
							|  |  |  |     faacEncConfigurationPtr faac_cfg; | 
					
						
							|  |  |  |     unsigned long samples_input, max_bytes_output; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* number of channels */ | 
					
						
							| 
									
										
										
										
											2008-09-20 11:13:14 +00:00
										 |  |  |     if (avctx->channels < 1 || avctx->channels > 6) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2008-09-20 11:13:14 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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) { | 
					
						
							| 
									
										
										
										
											2005-12-22 01:10:11 +00:00
										 |  |  |         av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version); | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |         faacEncClose(s->faac_handle); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* put the options in the configuration struct */ | 
					
						
							| 
									
										
										
										
											2007-05-02 13:49:08 +00:00
										 |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |     faac_cfg->mpegVersion = MPEG4; | 
					
						
							|  |  |  |     faac_cfg->useTns = 0; | 
					
						
							|  |  |  |     faac_cfg->allowMidside = 1; | 
					
						
							| 
									
										
										
										
											2005-08-21 20:27:00 +00:00
										 |  |  |     faac_cfg->bitRate = avctx->bit_rate / avctx->channels; | 
					
						
							| 
									
										
										
										
											2006-01-10 20:07:29 +00:00
										 |  |  |     faac_cfg->bandWidth = avctx->cutoff; | 
					
						
							| 
									
										
										
										
											2005-08-21 20:27:00 +00:00
										 |  |  |     if(avctx->flags & CODEC_FLAG_QSCALE) { | 
					
						
							|  |  |  |         faac_cfg->bitRate = 0; | 
					
						
							|  |  |  |         faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2006-02-08 01:10:07 +00:00
										 |  |  |     faac_cfg->outputFormat = 1; | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |     faac_cfg->inputFormat = FAAC_INPUT_16BIT; | 
					
						
							| 
									
										
										
										
											2011-06-15 10:57:26 +02:00
										 |  |  |     if (avctx->channels > 2) | 
					
						
							|  |  |  |         memcpy(faac_cfg->channel_map, channel_maps[avctx->channels-3], | 
					
						
							|  |  |  |                avctx->channels * sizeof(int)); | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-28 09:56:15 +00:00
										 |  |  |         unsigned char *buffer = NULL; | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |         unsigned long decoder_specific_info_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer, | 
					
						
							|  |  |  |                                            &decoder_specific_info_size)) { | 
					
						
							| 
									
										
										
										
											2007-02-28 09:56:15 +00:00
										 |  |  |             avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE); | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |             avctx->extradata_size = decoder_specific_info_size; | 
					
						
							| 
									
										
										
										
											2007-02-28 09:56:15 +00:00
										 |  |  |             memcpy(avctx->extradata, buffer, avctx->extradata_size); | 
					
						
							| 
									
										
										
										
											2006-02-08 01:10:07 +00:00
										 |  |  |             faac_cfg->outputFormat = 0; | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-02-28 09:56:15 +00:00
										 |  |  | #undef free
 | 
					
						
							|  |  |  |         free(buffer); | 
					
						
							|  |  |  | #define free please_use_av_free
 | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-08 01:10:07 +00:00
										 |  |  |     if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-11-11 20:54:48 +00:00
										 |  |  | static int Faac_encode_frame(AVCodecContext *avctx, | 
					
						
							|  |  |  |                              unsigned char *frame, int buf_size, void *data) | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     FaacAudioContext *s = avctx->priv_data; | 
					
						
							|  |  |  |     int bytes_written; | 
					
						
							| 
									
										
										
										
											2011-01-29 18:45:32 +00:00
										 |  |  |     int num_samples = data ? avctx->frame_size : 0; | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     bytes_written = faacEncEncode(s->faac_handle, | 
					
						
							|  |  |  |                                   data, | 
					
						
							| 
									
										
										
										
											2011-01-29 18:45:32 +00:00
										 |  |  |                                   num_samples * avctx->channels, | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |                                   frame, | 
					
						
							|  |  |  |                                   buf_size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return bytes_written; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-21 03:11:20 +00:00
										 |  |  | static av_cold int Faac_encode_close(AVCodecContext *avctx) | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     FaacAudioContext *s = avctx->priv_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     av_freep(&avctx->coded_frame); | 
					
						
							| 
									
										
										
										
											2007-02-28 09:56:15 +00:00
										 |  |  |     av_freep(&avctx->extradata); | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     faacEncClose(s->faac_handle); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-21 21:58:54 +00:00
										 |  |  | static const AVProfile profiles[] = { | 
					
						
							|  |  |  |     { FF_PROFILE_AAC_MAIN, "Main" }, | 
					
						
							|  |  |  |     { FF_PROFILE_AAC_LOW,  "LC"   }, | 
					
						
							|  |  |  |     { FF_PROFILE_AAC_SSR,  "SSR"  }, | 
					
						
							|  |  |  |     { FF_PROFILE_AAC_LTP,  "LTP"  }, | 
					
						
							|  |  |  |     { FF_PROFILE_UNKNOWN }, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-25 21:40:11 +00:00
										 |  |  | AVCodec ff_libfaac_encoder = { | 
					
						
							| 
									
										
										
										
											2011-07-17 12:54:31 +02:00
										 |  |  |     .name           = "libfaac", | 
					
						
							|  |  |  |     .type           = AVMEDIA_TYPE_AUDIO, | 
					
						
							|  |  |  |     .id             = CODEC_ID_AAC, | 
					
						
							|  |  |  |     .priv_data_size = sizeof(FaacAudioContext), | 
					
						
							|  |  |  |     .init           = Faac_encode_init, | 
					
						
							|  |  |  |     .encode         = Faac_encode_frame, | 
					
						
							|  |  |  |     .close          = Faac_encode_close, | 
					
						
							| 
									
										
										
										
											2011-01-29 18:45:32 +00:00
										 |  |  |     .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, | 
					
						
							| 
									
										
										
										
											2010-11-12 11:04:40 +00:00
										 |  |  |     .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, | 
					
						
							| 
									
										
										
										
											2008-06-12 21:50:13 +00:00
										 |  |  |     .long_name = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Codec)"), | 
					
						
							| 
									
										
										
										
											2011-01-21 21:58:54 +00:00
										 |  |  |     .profiles = NULL_IF_CONFIG_SMALL(profiles), | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | }; |