OSDN Git Service

- Add CoreAudio AAC as one of the encoder on Mac OS X.
authorritsuka <ritsuka@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sat, 23 May 2009 09:46:36 +0000 (09:46 +0000)
committerritsuka <ritsuka@b64f7644-9d1e-0410-96f1-a4d463321fa5>
Sat, 23 May 2009 09:46:36 +0000 (09:46 +0000)
- Remove hb_init() and hb_init_express() macro. Rename hb_init_real() to hb_init()
- Add two more bitrate combination for audio codecs in common.h

git-svn-id: svn://localhost/HandBrake/trunk@2441 b64f7644-9d1e-0410-96f1-a4d463321fa5

13 files changed:
libhb/common.c
libhb/common.h
libhb/hb.c
libhb/hb.h
libhb/internal.h
libhb/module.defs
libhb/muxmkv.c
libhb/platform/macosx/encca_aac.c [new file with mode: 0644]
libhb/work.c
macosx/Controller.mm
macosx/HandBrake.xcodeproj/project.pbxproj
test/module.defs
test/test.c

index 88a8ea8..b84f907 100644 (file)
@@ -31,7 +31,8 @@ hb_rate_t hb_audio_bitrates[] =
 { {  "32",  32 }, {  "40",  40 }, {  "48",  48 }, {  "56",  56 },
   {  "64",  64 }, {  "80",  80 }, {  "96",  96 }, { "112", 112 },
   { "128", 128 }, { "160", 160 }, { "192", 192 }, { "224", 224 },
-  { "256", 256 }, { "320", 320 }, { "384", 384 } };
+  { "256", 256 }, { "320", 320 }, { "384", 384 }, { "448", 448 }
+  { "768", 768 } };
 int hb_audio_bitrates_count = sizeof( hb_audio_bitrates ) /
                               sizeof( hb_rate_t );
 int hb_audio_bitrates_default = 8; /* 128 kbps */
@@ -227,6 +228,7 @@ int hb_calc_bitrate( hb_job_t * job, int size )
         switch( audio->config.out.codec )
         {
             case HB_ACODEC_FAAC:
+            case HB_ACODEC_CA_AAC:
             case HB_ACODEC_VORBIS:
                 samples_per_frame = 1024;
                 break;
index 224b40c..d7649f4 100644 (file)
@@ -286,6 +286,7 @@ struct hb_job_s
 #define HB_ACODEC_LPCM   0x002000
 #define HB_ACODEC_DCA    0x004000
 #define HB_ACODEC_FFMPEG 0x008000
+#define HB_ACODEC_CA_AAC 0x010000
 
 /* Audio Mixdown */
 /* define some masks, used to extract the various information from the HB_AMIXDOWN_XXXX values */
@@ -675,6 +676,7 @@ extern hb_work_object_t hb_declpcm;
 extern hb_work_object_t hb_encfaac;
 extern hb_work_object_t hb_enclame;
 extern hb_work_object_t hb_encvorbis;
+extern hb_work_object_t hb_encca_aac;
 
 #define FILTER_OK      0
 #define FILTER_DELAY   1
index 661e1df..4f48420 100644 (file)
@@ -86,7 +86,7 @@ void hb_register( hb_work_object_t * w )
  * @param update_check signals libhb to check for updated version from HandBrake website.
  * @return Handle to hb_handle_t for use on all subsequent calls to libhb.
  */
-hb_handle_t * hb_init_real( int verbose, int update_check )
+hb_handle_t * hb_init( int verbose, int update_check )
 {
     hb_handle_t * h = calloc( sizeof( hb_handle_t ), 1 );
     uint64_t      date;
@@ -150,11 +150,31 @@ hb_handle_t * hb_init_real( int verbose, int update_check )
     h->die         = 0;
     h->main_thread = hb_thread_init( "libhb", thread_func, h,
                                      HB_NORMAL_PRIORITY );
+    hb_register( &hb_sync );
+       hb_register( &hb_decmpeg2 );
+       hb_register( &hb_decvobsub );
+    hb_register( &hb_encvobsub );
+    hb_register( &hb_deccc608 );
+       hb_register( &hb_render );
+       hb_register( &hb_encavcodec );
+       hb_register( &hb_encxvid );
+       hb_register( &hb_encx264 );
+    hb_register( &hb_enctheora );
+       hb_register( &hb_deca52 );
+       hb_register( &hb_decdca );
+       hb_register( &hb_decavcodec );
+       hb_register( &hb_decavcodecv );
+       hb_register( &hb_decavcodecvi );
+       hb_register( &hb_decavcodecai );
+       hb_register( &hb_declpcm );
+       hb_register( &hb_encfaac );
+       hb_register( &hb_enclame );
+       hb_register( &hb_encvorbis );
+#ifdef __APPLE__
+       hb_register( &hb_encca_aac );
+#endif
 
     return h;
-
-       /* Set the scan count to start at 0 */
-       //scan_count = 0;
 }
 
 /**
@@ -230,13 +250,13 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
     hb_register( &hb_sync );
        hb_register( &hb_decmpeg2 );
        hb_register( &hb_decvobsub );
-        hb_register( &hb_encvobsub );
-        hb_register( &hb_deccc608 );
+    hb_register( &hb_encvobsub );
+    hb_register( &hb_deccc608 );
        hb_register( &hb_render );
        hb_register( &hb_encavcodec );
        hb_register( &hb_encxvid );
        hb_register( &hb_encx264 );
-        hb_register( &hb_enctheora );
+    hb_register( &hb_enctheora );
        hb_register( &hb_deca52 );
        hb_register( &hb_decdca );
        hb_register( &hb_decavcodec );
@@ -247,6 +267,9 @@ hb_handle_t * hb_init_dl( int verbose, int update_check )
        hb_register( &hb_encfaac );
        hb_register( &hb_enclame );
        hb_register( &hb_encvorbis );
+#ifdef __APPLE__
+       hb_register( &hb_encca_aac );
+#endif
 
        return h;
 }
@@ -1301,7 +1324,7 @@ int hb_get_scancount( hb_handle_t * h)
  }
 
 /**
- * Closes access to libhb by freeing the hb_handle_t handle ontained in hb_init_real.
+ * Closes access to libhb by freeing the hb_handle_t handle ontained in hb_init.
  * @param _h Pointer to handle to hb_handle_t.
  */
 void hb_close( hb_handle_t ** _h )
index 3cf308e..cc7a7ee 100644 (file)
@@ -14,51 +14,9 @@ extern "C" {
 #define HB_DEBUG_NONE 0
 #define HB_DEBUG_ALL  1
 void          hb_register( hb_work_object_t * );
-hb_handle_t * hb_init_real( int verbose, int update_check );
+hb_handle_t * hb_init( int verbose, int update_check );
 hb_handle_t * hb_init_dl ( int verbose, int update_check ); // hb_init for use with dylib
 
-#define hb_init(v,u) \
-hb_init_real( v, u ); \
-hb_register( &hb_sync ); \
-hb_register( &hb_decmpeg2 ); \
-hb_register( &hb_decvobsub ); \
-hb_register( &hb_encvobsub ); \
-hb_register( &hb_deccc608 ); \
-hb_register( &hb_render ); \
-hb_register( &hb_encavcodec ); \
-hb_register( &hb_encxvid ); \
-hb_register( &hb_encx264 ); \
-hb_register( &hb_enctheora ); \
-hb_register( &hb_deca52 ); \
-hb_register( &hb_decdca ); \
-hb_register( &hb_decavcodec ); \
-hb_register( &hb_decavcodecv ); \
-hb_register( &hb_decavcodecvi ); \
-hb_register( &hb_decavcodecai ); \
-hb_register( &hb_declpcm ); \
-hb_register( &hb_encfaac ); \
-hb_register( &hb_enclame ); \
-hb_register( &hb_encvorbis ); \
-
-#define hb_init_express(v,u) \
-hb_init_real( v, u ); \
-hb_register( &hb_sync ); \
-hb_register( &hb_decmpeg2 ); \
-hb_register( &hb_decvobsub ); \
-hb_register( &hb_encvobsub ); \
-hb_register( &hb_deccc608 ); \
-hb_register( &hb_render ); \
-hb_register( &hb_encavcodec ); \
-hb_register( &hb_encx264 ); \
-hb_register( &hb_deca52 ); \
-hb_register( &hb_decdca ); \
-hb_register( &hb_decavcodec ); \
-hb_register( &hb_decavcodecv ); \
-hb_register( &hb_decavcodecvi ); \
-hb_register( &hb_decavcodecai ); \
-hb_register( &hb_declpcm ); \
-hb_register( &hb_encfaac ); \
-
 /* hb_get_version() */
 char        * hb_get_version( hb_handle_t * );
 int           hb_get_build( hb_handle_t * );
index b05e50a..1e5afdc 100644 (file)
@@ -271,7 +271,8 @@ enum
     WORK_DECLPCM,
     WORK_ENCFAAC,
     WORK_ENCLAME,
-    WORK_ENCVORBIS
+    WORK_ENCVORBIS,
+    WORK_ENC_CA_AAC
 };
 
 enum
index 725ebc1..e5ecf97 100644 (file)
@@ -41,6 +41,7 @@ ifeq ($(BUILD.system),cygwin)
     LIBHB.GCC.D += SYS_CYGWIN
 else ifeq ($(BUILD.system),darwin)
     LIBHB.GCC.D += SYS_DARWIN
+    LIBHB.c += $(wildcard $(LIBHB.src/)platform/macosx/*.c)
 else ifeq ($(BUILD.system),linux)
     LIBHB.GCC.D += SYS_LINUX _LARGEFILE_SOURCE _FILE_OFFSET_BITS=64
 else ifeq ($(BUILD.system),mingw)
index 04f9ae5..6a8a55c 100644 (file)
@@ -226,6 +226,7 @@ static int MKVInit( hb_mux_object_t * m )
                 }
                 break;
             case HB_ACODEC_FAAC:
+            case HB_ACODEC_CA_AAC:
                 track->codecPrivate = audio->priv.config.aac.bytes;
                 track->codecPrivateSize = audio->priv.config.aac.length;
                 track->codecID = MK_ACODEC_AAC;
diff --git a/libhb/platform/macosx/encca_aac.c b/libhb/platform/macosx/encca_aac.c
new file mode 100644 (file)
index 0000000..69b29ec
--- /dev/null
@@ -0,0 +1,341 @@
+/* This file is part of the HandBrake source code.
+ Homepage: <http://handbrake.fr/>.
+ It may be used under the terms of the GNU General Public License. */
+
+#include "hb.h"
+#include <AudioToolbox/AudioToolbox.h>
+#include <CoreAudio/CoreAudio.h>
+
+int     encCoreAudioInit( hb_work_object_t *, hb_job_t * );
+int     encCoreAudioWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
+void    encCoreAudioClose( hb_work_object_t * );
+
+hb_work_object_t hb_encca_aac =
+{
+    WORK_ENC_CA_AAC,
+    "AAC encoder (Apple)",
+    encCoreAudioInit,
+    encCoreAudioWork,
+    encCoreAudioClose
+};
+
+struct hb_work_private_s
+{
+    hb_job_t *job;
+    
+    AudioConverterRef converter;
+    uint8_t  *obuf;
+    uint8_t  *buf;
+    hb_list_t *list;
+    unsigned long isamples, isamplesiz, omaxpacket, nchannels;
+    uint64_t pts, ibytes;
+};
+
+#define MP4ESDescrTag                   0x03
+#define MP4DecConfigDescrTag            0x04
+#define MP4DecSpecificDescrTag          0x05
+
+// based off of mov_mp4_read_descr_len from mov.c in ffmpeg's libavformat
+static int readDescrLen(UInt8 **buffer)
+{
+       int len = 0;
+       int count = 4;
+       while (count--) {
+               int c = *(*buffer)++;
+               len = (len << 7) | (c & 0x7f);
+               if (!(c & 0x80))
+                       break;
+       }
+       return len;
+}
+
+// based off of mov_mp4_read_descr from mov.c in ffmpeg's libavformat
+static int readDescr(UInt8 **buffer, int *tag)
+{
+       *tag = *(*buffer)++;
+       return readDescrLen(buffer);
+}
+
+// based off of mov_read_esds from mov.c in ffmpeg's libavformat
+static long ReadESDSDescExt(void* descExt, UInt8 **buffer, int *size, int versionFlags)
+{
+       UInt8 *esds = (UInt8 *) descExt;
+       int tag, len;
+       *size = 0;
+
+    if (versionFlags)
+        esds += 4;             // version + flags
+       readDescr(&esds, &tag);
+       esds += 2;              // ID
+       if (tag == MP4ESDescrTag)
+               esds++;         // priority
+
+       readDescr(&esds, &tag);
+       if (tag == MP4DecConfigDescrTag) {
+               esds++;         // object type id
+               esds++;         // stream type
+               esds += 3;      // buffer size db
+               esds += 4;      // max bitrate
+               esds += 4;      // average bitrate
+
+               len = readDescr(&esds, &tag);
+               if (tag == MP4DecSpecificDescrTag) {
+                       *buffer = calloc(1, len + 8);
+                       if (*buffer) {
+                               memcpy(*buffer, esds, len);
+                               *size = len;
+                       }
+               }
+       }
+
+       return noErr;
+}
+
+/***********************************************************************
+ * hb_work_encCoreAudio_init
+ ***********************************************************************
+ *
+ **********************************************************************/
+int encCoreAudioInit( 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;
+    AudioStreamBasicDescription input, output;
+    UInt32 tmp, tmpsiz = sizeof( tmp );
+    OSStatus err;
+
+    w->private_data = pv;
+    pv->job = job;
+
+    // pass the number of channels used into the private work data
+    pv->nchannels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT( audio->config.out.mixdown );
+
+    bzero( &input, sizeof( AudioStreamBasicDescription ) );
+    input.mSampleRate = ( Float64 ) audio->config.out.samplerate;
+    input.mFormatID = kAudioFormatLinearPCM;
+    input.mFormatFlags = kLinearPCMFormatFlagIsFloat | kAudioFormatFlagsNativeEndian;
+    input.mBytesPerPacket = 4 * pv->nchannels;
+    input.mFramesPerPacket = 1;
+    input.mBytesPerFrame = input.mBytesPerPacket * input.mFramesPerPacket;
+    input.mChannelsPerFrame = pv->nchannels;
+    input.mBitsPerChannel = 32;
+
+    bzero( &output, sizeof( AudioStreamBasicDescription ) );
+    output.mSampleRate = ( Float64 ) audio->config.out.samplerate;
+    output.mFormatID = kAudioFormatMPEG4AAC;
+    output.mChannelsPerFrame = pv->nchannels;
+    // let CoreAudio decide the rest...
+
+    // initialise encoder
+    err = AudioConverterNew( &input, &output, &pv->converter );
+    if( err != noErr)
+    {
+        hb_log( "Error creating an AudioConverter %x %d", err, output.mBytesPerFrame );
+        *job->die = 1;
+        return 0;
+    }
+
+    if( audio->config.out.mixdown == HB_AMIXDOWN_6CH && audio->config.in.codec == HB_ACODEC_AC3 )
+    {
+        SInt32 channelMap[6] = { 2, 1, 3, 4, 5, 0 };
+        AudioConverterSetProperty( pv->converter, kAudioConverterChannelMap,
+                                   sizeof( channelMap ), channelMap );
+    }
+
+    // set encoder quality to maximum
+    tmp = kAudioConverterQuality_Max;
+    AudioConverterSetProperty( pv->converter, kAudioConverterCodecQuality,
+                               sizeof( tmp ), &tmp );
+
+    // set encoder bitrate control mode to constrained variable
+    tmp = kAudioCodecBitRateControlMode_VariableConstrained;
+    AudioConverterSetProperty( pv->converter, kAudioCodecPropertyBitRateControlMode,
+                              sizeof( tmp ), &tmp );
+
+    // get available bitrates
+    AudioValueRange *bitrates;
+    ssize_t bitrateCounts, n;
+    err = AudioConverterGetPropertyInfo( pv->converter, kAudioConverterApplicableEncodeBitRates,
+                                         &tmpsiz, NULL);
+    bitrates = malloc( tmpsiz );
+    err = AudioConverterGetProperty( pv->converter, kAudioConverterApplicableEncodeBitRates,
+                                     &tmpsiz, bitrates);
+    bitrateCounts = tmpsiz / sizeof( AudioValueRange );
+
+    // set bitrate
+    tmp = audio->config.out.bitrate * 1000;
+    if( tmp < bitrates[0].mMinimum )
+        tmp = bitrates[0].mMinimum;
+    if( tmp > bitrates[bitrateCounts-1].mMinimum )
+        tmp = bitrates[bitrateCounts-1].mMinimum;
+    free( bitrates );
+    AudioConverterSetProperty( pv->converter, kAudioConverterEncodeBitRate,
+                              sizeof( tmp ), &tmp );
+
+    // get real input
+    tmpsiz = sizeof( input );
+    AudioConverterGetProperty( pv->converter,
+                               kAudioConverterCurrentInputStreamDescription,
+                               &tmpsiz, &input );
+    // get real output
+    tmpsiz = sizeof( output );
+    AudioConverterGetProperty( pv->converter,
+                               kAudioConverterCurrentOutputStreamDescription,
+                               &tmpsiz, &output );
+
+    // set sizes
+    pv->isamplesiz = input.mBytesPerPacket;
+    pv->isamples   = output.mFramesPerPacket;
+
+    // get maximum output size
+    AudioConverterGetProperty( pv->converter,
+                               kAudioConverterPropertyMaximumOutputPacketSize,
+                               &tmpsiz, &tmp );
+    pv->omaxpacket = tmp;
+
+    // get magic cookie (elementary stream descriptor)
+    tmp = HB_CONFIG_MAX_SIZE;
+    AudioConverterGetProperty( pv->converter,
+                               kAudioConverterCompressionMagicCookie,
+                               &tmp, w->config->aac.bytes );
+    // CoreAudio returns a complete ESDS, but we only need
+    // the DecoderSpecific info.
+    UInt8* buffer;
+    ReadESDSDescExt(w->config->aac.bytes, &buffer, &tmpsiz, 0);
+    w->config->aac.length = tmpsiz;
+    memmove( w->config->aac.bytes, buffer,
+             w->config->aac.length );
+
+    pv->list = hb_list_init();
+    pv->buf = NULL;
+
+    return 0;
+}
+
+/***********************************************************************
+ * Close
+ ***********************************************************************
+ *
+ **********************************************************************/
+void encCoreAudioClose( hb_work_object_t * w )
+{
+    hb_work_private_t * pv = w->private_data;
+
+    if( pv->converter )
+    {
+        AudioConverterDispose( pv->converter );
+        hb_list_empty( &pv->list );
+        free( pv->obuf );
+        free( pv->buf );
+        free( pv );
+        w->private_data = NULL;
+    }
+}
+
+/* Called whenever necessary by AudioConverterFillComplexBuffer */
+static OSStatus inInputDataProc( AudioConverterRef converter, UInt32 *npackets,
+                          AudioBufferList *buffers,
+                          AudioStreamPacketDescription** ignored,
+                          void *userdata )
+{
+    hb_work_private_t *pv = userdata;
+    pv->ibytes = hb_list_bytes( pv->list );
+
+    if( pv->ibytes == 0 ) {
+        *npackets = 0;
+        return noErr;
+    }
+
+    if( pv->buf != NULL )
+        free( pv->buf );
+
+    uint64_t pts, pos;
+    pv->ibytes = buffers->mBuffers[0].mDataByteSize = MIN( *npackets * pv->isamplesiz, pv->ibytes );
+    buffers->mBuffers[0].mData = pv->buf = malloc( buffers->mBuffers[0].mDataByteSize );
+
+    hb_list_getbytes( pv->list, buffers->mBuffers[0].mData,
+                      buffers->mBuffers[0].mDataByteSize, &pts, &pos );
+
+    *npackets = buffers->mBuffers[0].mDataByteSize / pv->isamplesiz;
+
+    /* transform data from [-32768,32767] to [-1.0,1.0] */
+    float *fdata = buffers->mBuffers[0].mData;
+    int i;
+
+    for( i = 0; i < *npackets * pv->nchannels; i++ )
+        fdata[i] = fdata[i] / 32768.f;
+
+    return noErr;
+}
+
+/***********************************************************************
+ * Encode
+ ***********************************************************************
+ *
+ **********************************************************************/
+static hb_buffer_t * Encode( hb_work_object_t * w )
+{
+    hb_work_private_t * pv = w->private_data;
+    UInt32 npackets = 1;
+
+    /* check if we need more data */
+    if( hb_list_bytes( pv->list ) < pv->isamples * pv->isamplesiz )
+        return NULL;
+
+    hb_buffer_t * obuf;
+    AudioStreamPacketDescription odesc = { 0 };
+    AudioBufferList obuflist = { .mNumberBuffers = 1,
+                                 .mBuffers = { { .mNumberChannels = pv->nchannels } },
+                               };
+
+    obuf = hb_buffer_init( pv->omaxpacket );
+    obuflist.mBuffers[0].mDataByteSize = obuf->size;
+    obuflist.mBuffers[0].mData = obuf->data;
+
+    AudioConverterFillComplexBuffer( pv->converter, inInputDataProc, pv, 
+                                     &npackets, &obuflist, &odesc );
+
+    if( odesc.mDataByteSize == 0 )
+        return NULL;
+
+    obuf->start = pv->pts;
+    pv->pts += 90000LL * pv->isamples / w->audio->config.out.samplerate;
+    obuf->stop  = pv->pts;
+    obuf->size  = odesc.mDataByteSize;
+    obuf->frametype = HB_FRAME_AUDIO;
+
+    return obuf;
+}
+
+/***********************************************************************
+ * Work
+ ***********************************************************************
+ *
+ **********************************************************************/
+int encCoreAudioWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
+                  hb_buffer_t ** buf_out )
+{
+    hb_work_private_t * pv = w->private_data;
+    hb_buffer_t * buf;
+
+    if( (*buf_in)->size <= 0 )
+    {
+        // EOF on input - send it downstream & say we're done
+        *buf_out = *buf_in;
+        *buf_in = NULL;
+        return HB_WORK_DONE;
+    }
+
+    hb_list_add( pv->list, *buf_in );
+    *buf_in = NULL;
+
+    *buf_out = buf = Encode( w );
+
+    while( buf )
+    {
+        buf->next = Encode( w );
+        buf       = buf->next;
+    }
+
+    return HB_WORK_OK;
+}
index 59dea5d..21232de 100644 (file)
@@ -106,6 +106,7 @@ hb_work_object_t * hb_codec_encoder( int codec )
         case HB_ACODEC_FAAC:   return hb_get_work( WORK_ENCFAAC );
         case HB_ACODEC_LAME:   return hb_get_work( WORK_ENCLAME );
         case HB_ACODEC_VORBIS: return hb_get_work( WORK_ENCVORBIS );
+        case HB_ACODEC_CA_AAC:  return hb_get_work( WORK_ENC_CA_AAC );
     }
     return NULL;
 }
@@ -329,8 +330,9 @@ void hb_display_job_info( hb_job_t * job )
             else
             {
                 hb_log( "   + encoder: %s", ( audio->config.out.codec == HB_ACODEC_FAAC ) ?
-                    "faac" : ( ( audio->config.out.codec == HB_ACODEC_LAME ) ? "lame" :
-                    "vorbis" ) );
+                    "faac" : ( ( audio->config.out.codec == HB_ACODEC_LAME ) ?
+                    "lame" : ( ( audio->config.out.codec == HB_ACODEC_CA_AAC ) ?
+                              "ca_aac" : "vorbis"  ) ) );
                 hb_log( "     + bitrate: %d kbps, samplerate: %d Hz", audio->config.out.bitrate, audio->config.out.samplerate );            
             }
         }
index 250c8fe..9e58356 100644 (file)
@@ -4787,10 +4787,14 @@ the user is using "Custom" settings by determining the sender*/
         {
             case 0:
                 /* MP4 */
-                // AAC
+                // FAAC
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_FAAC];
-                
+
+                // CA_AAC
+                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (CoreAudio)" action: NULL keyEquivalent: @""];
+                [menuItem setTag: HB_ACODEC_CA_AAC];
+
                 // AC3 Passthru
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_AC3];
@@ -4798,9 +4802,12 @@ the user is using "Custom" settings by determining the sender*/
                 
             case 1:
                 /* MKV */
-                // AAC
+                // FAAC
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_FAAC];
+                // CA_AAC
+                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (CoreAudio)" action: NULL keyEquivalent: @""];
+                [menuItem setTag: HB_ACODEC_CA_AAC];
                 // AC3 Passthru
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_AC3];
@@ -5229,7 +5236,22 @@ the user is using "Custom" settings by determining the sender*/
                 maxbitrate = 160;
                 break;
             }
-            
+
+        case HB_ACODEC_CA_AAC:
+            /* check if we have a 6ch discrete conversion in either audio track */
+            if ([[mixdownPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
+            {
+                minbitrate = 128;
+                maxbitrate = 768;
+                break;
+            }
+            else
+            {
+                minbitrate = 64;
+                maxbitrate = 320;
+                break;
+            }
+
             case HB_ACODEC_LAME:
             /* Lame is happy using our min bitrate of 32 kbps */
             minbitrate = 32;
index 6738659..e1314c3 100644 (file)
@@ -57,6 +57,8 @@
                A2D7AD6D0C998AD30082CA33 /* pref-picture.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2D7AD640C998AD30082CA33 /* pref-picture.tiff */; };
                A2D7AD6E0C998AD30082CA33 /* Queue.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2D7AD650C998AD30082CA33 /* Queue.tiff */; };
                A2D7AD6F0C998AD30082CA33 /* Source.tiff in Resources */ = {isa = PBXBuildFile; fileRef = A2D7AD660C998AD30082CA33 /* Source.tiff */; };
+               A906A0510F7A7B210007A827 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A906A0500F7A7B210007A827 /* AudioToolbox.framework */; };
+               A906A0520F7A7B210007A827 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A906A0500F7A7B210007A827 /* AudioToolbox.framework */; };
                A9AC41DF0C918DB500DDF9B8 /* HBAdvancedController.m in Sources */ = {isa = PBXBuildFile; fileRef = A9AC41DD0C918DB500DDF9B8 /* HBAdvancedController.m */; };
                A9AC41E00C918DB500DDF9B8 /* HBAdvancedController.h in Headers */ = {isa = PBXBuildFile; fileRef = A9AC41DE0C918DB500DDF9B8 /* HBAdvancedController.h */; };
                D289A9F30DBBE7AC00CE614B /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D289A9F20DBBE7AC00CE614B /* CoreServices.framework */; };
                A2D7AD640C998AD30082CA33 /* pref-picture.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = "pref-picture.tiff"; sourceTree = "<group>"; };
                A2D7AD650C998AD30082CA33 /* Queue.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Queue.tiff; sourceTree = "<group>"; };
                A2D7AD660C998AD30082CA33 /* Source.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = Source.tiff; sourceTree = "<group>"; };
+               A906A0500F7A7B210007A827 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
                A9AC41DD0C918DB500DDF9B8 /* HBAdvancedController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = HBAdvancedController.m; sourceTree = "<group>"; };
                A9AC41DE0C918DB500DDF9B8 /* HBAdvancedController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HBAdvancedController.h; sourceTree = "<group>"; };
                D289A9F20DBBE7AC00CE614B /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
                                2713E6300F676510002E0A01 /* libhb.a in Frameworks */,
                                2774BE900F66F47100B65FC6 /* libbz2.dylib in Frameworks */,
                                2774BE920F66F48200B65FC6 /* libz.dylib in Frameworks */,
+                               A906A0520F7A7B210007A827 /* AudioToolbox.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                2713E6420F676526002E0A01 /* libhb.a in Frameworks */,
                                2774BEC70F66F61A00B65FC6 /* libbz2.dylib in Frameworks */,
                                2774BEC80F66F61A00B65FC6 /* libz.dylib in Frameworks */,
+                               A906A0510F7A7B210007A827 /* AudioToolbox.framework in Frameworks */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                29B97323FDCFA39411CA2CEA /* Frameworks */ = {
                        isa = PBXGroup;
                        children = (
+                               A906A0500F7A7B210007A827 /* AudioToolbox.framework */,
                                A25962E00F15077500B3BF4E /* Quartz.framework */,
                                A20F47000EBB5EC2005B861B /* QTKit.framework */,
                                A20F46DB0EBB5E7A005B861B /* QuickTime.framework */,
index 0140823..9be48b4 100644 (file)
@@ -36,7 +36,7 @@ BUILD.out += $(TEST.install.exe)
 TEST.GCC.I += $(LIBHB.GCC.I)
 
 ifeq ($(BUILD.system),darwin)
-    TEST.GCC.f += IOKit CoreServices
+    TEST.GCC.f += IOKit CoreServices AudioToolbox
     TEST.GCC.l += bz2 z
 else ifeq ($(BUILD.system),linux)
     TEST.GCC.l += bz2 z pthread dl m
index 44e44d1..3c93cec 100644 (file)
@@ -2747,6 +2747,12 @@ static int get_acodec_for_string( char *codec )
     {
         return HB_ACODEC_VORBIS;
     }
+#ifdef __APPLE__
+    else if( !strcasecmp( codec, "ca_aac") )
+    {
+        return HB_ACODEC_CA_AAC;
+    }
+#endif
     else
     {
         return -1;