| 
									
										
										
										
											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
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2007-08-22 15:03:14 +00:00
										 |  |  |  * @file libfaac.c | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 */ | 
					
						
							|  |  |  |     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) { | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bytes_written = faacEncEncode(s->faac_handle, | 
					
						
							|  |  |  |                                   data, | 
					
						
							|  |  |  |                                   avctx->frame_size * avctx->channels, | 
					
						
							|  |  |  |                                   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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-02 11:20:24 +00:00
										 |  |  | AVCodec libfaac_encoder = { | 
					
						
							|  |  |  |     "libfaac", | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  |     CODEC_TYPE_AUDIO, | 
					
						
							|  |  |  |     CODEC_ID_AAC, | 
					
						
							|  |  |  |     sizeof(FaacAudioContext), | 
					
						
							|  |  |  |     Faac_encode_init, | 
					
						
							|  |  |  |     Faac_encode_frame, | 
					
						
							| 
									
										
										
										
											2008-04-27 22:39:51 +00:00
										 |  |  |     Faac_encode_close, | 
					
						
							| 
									
										
										
										
											2008-07-31 10:47:31 +00:00
										 |  |  |     .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, | 
					
						
							| 
									
										
										
										
											2008-06-12 21:50:13 +00:00
										 |  |  |     .long_name = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Codec)"), | 
					
						
							| 
									
										
										
										
											2003-10-04 09:53:34 +00:00
										 |  |  | }; |