OSDN Git Service

RIO-7248: Update the author driver to support new audio encoding types.
authorPacketVideo CM <engbuild@pv.com>
Wed, 23 Sep 2009 23:24:29 +0000 (16:24 -0700)
committerPacketVideo CM <engbuild@pv.com>
Wed, 23 Sep 2009 23:24:29 +0000 (16:24 -0700)
android/author/android_audio_input.cpp
android/author/android_audio_input.h
android/author/android_camera_input.cpp
android/author/authordriver.cpp
android/author/authordriver.h
engines/2way/src/pv_2way_sdkinfo.h
engines/author/src/pv_author_sdkinfo.h
engines/player/src/pv_player_sdkinfo.h

index 73b9934..b52dbe4 100644 (file)
@@ -44,12 +44,14 @@ static const int32 AUTO_RAMP_START_MS = 300;
 static const int32 AUTO_RAMP_DURATION_MS = 300;
 
 ////////////////////////////////////////////////////////////////////////////
-AndroidAudioInput::AndroidAudioInput()
+AndroidAudioInput::AndroidAudioInput(uint32 audioSource)
     : OsclTimerObject(OsclActiveObject::EPriorityNominal, "AndroidAudioInput"),
     iCmdIdCounter(0),
     iPeer(NULL),
     iThreadLoggedOn(false),
-    iAudioSamplingRate(8000),
+    iAudioNumChannels(DEFAULT_AUDIO_NUMBER_OF_CHANNELS),
+    iAudioSamplingRate(DEFAULT_AUDIO_SAMPLING_RATE),
+    iAudioSource(audioSource),
     iDataEventCounter(0),
     iWriteCompleteAO(NULL),
     iTimeStamp(0),
@@ -76,8 +78,6 @@ AndroidAudioInput::AndroidAudioInput()
 
     {
         iAudioFormat=PVMF_MIME_FORMAT_UNKNOWN;
-        iAudioNumChannelsValid=false;
-        iAudioSamplingRateValid=false;
         iExitAudioThread=false;
 
         iCommandCounter=0;
@@ -512,29 +512,52 @@ OSCL_EXPORT_REF PVMFStatus AndroidAudioInput::getParametersSync(PvmiMIOSession s
             pv_mime_strcmp(identifier, OUTPUT_FORMATS_CUR_QUERY) == 0)
     {
         num_parameter_elements = 1;
-        status = AllocateKvp(parameters, OUTPUT_FORMATS_VALTYPE, num_parameter_elements);
+        status = AllocateKvp(parameters, (PvmiKeyType)OUTPUT_FORMATS_VALTYPE, num_parameter_elements);
         if(status != PVMFSuccess)
         {
-            LOGV("AllocateKvp failed");
-        }
-        else
-        {
-            parameters[0].value.pChar_value = (char*)PVMF_MIME_PCM16;
+            LOGE("AndroidAudioInput::getParametersSync() OUTPUT_FORMATS_VALTYPE AllocateKvp failed");
+            return status;
         }
+
+        parameters[0].value.pChar_value = (char*)PVMF_MIME_PCM16;
     }
     else if(pv_mime_strcmp(identifier, OUTPUT_TIMESCALE_CUR_QUERY) == 0)
     {
         num_parameter_elements = 1;
-        status = AllocateKvp(parameters, OUTPUT_TIMESCALE_CUR_VALUE, num_parameter_elements);
+        status = AllocateKvp(parameters, (PvmiKeyType)OUTPUT_TIMESCALE_CUR_VALUE, num_parameter_elements);
         if(status != PVMFSuccess)
         {
-            LOGV("AllocateKvp failed");
+            LOGE("AndroidAudioInput::getParametersSync() OUTPUT_TIMESCALE_CUR_VALUE AllocateKvp failed");
             return status;
         }
 
         // XXX is it okay to hardcode this as the timescale?
         parameters[0].value.uint32_value = 1000;
     }
+    else if (pv_mime_strcmp(identifier, AUDIO_OUTPUT_SAMPLING_RATE_CUR_QUERY) == 0)
+    {
+        num_parameter_elements = 1;
+        status = AllocateKvp(parameters, (PvmiKeyType)AUDIO_OUTPUT_SAMPLING_RATE_CUR_QUERY, num_parameter_elements);
+        if (status != PVMFSuccess)
+        {
+            LOGE("AndroidAudioInput::getParametersSync() AUDIO_OUTPUT_SAMPLING_RATE_CUR_QUERY AllocateKvp failed");
+            return status;
+        }
+
+        parameters[0].value.uint32_value = iAudioSamplingRate;
+    }
+    else if (pv_mime_strcmp(identifier, AUDIO_OUTPUT_NUM_CHANNELS_CUR_QUERY) == 0)
+    {
+        num_parameter_elements = 1;
+        status = AllocateKvp(parameters, (PvmiKeyType)AUDIO_OUTPUT_NUM_CHANNELS_CUR_QUERY, num_parameter_elements);
+        if (status != PVMFSuccess)
+        {
+            LOGE("AndroidAudioInput::getParametersSync() AUDIO_OUTPUT_NUM_CHANNELS_CUR_QUERY AllocateKvp failed");
+            return status;
+        }
+
+        parameters[0].value.uint32_value = iAudioNumChannels;
+    }
 
     return status;
 }
@@ -638,6 +661,32 @@ OSCL_EXPORT_REF PVMFStatus AndroidAudioInput::verifyParametersSync(PvmiMIOSessio
 }
 
 ////////////////////////////////////////////////////////////////////////////
+bool AndroidAudioInput::setAudioSamplingRate(int32 iSamplingRate)
+{
+    LOGV("AndroidAudioInput::setAudioSamplingRate( %d )", iSamplingRate);
+
+    if (iSamplingRate == 0)
+    {
+        // Setting sampling rate to zero will cause a crash
+        LOGV("AndroidAudioInput::setAudioSamplingRate() invalid sampling rate.  Return false.");
+        return false;
+    }
+
+    iAudioSamplingRate = iSamplingRate;
+    LOGV("AndroidAudioInput::setAudioSamplingRate() iAudioSamplingRate %d set", iAudioSamplingRate);
+    return true;
+}
+////////////////////////////////////////////////////////////////////////////
+bool AndroidAudioInput::setAudioNumChannels(int32 iNumChannels)
+{
+    LOGV("AndroidAudioInput::setAudioNumChannels( %d )", iNumChannels);
+
+    iAudioNumChannels = iNumChannels;
+    LOGV("AndroidAudioInput::setAudioNumChannels() iAudioNumChannels %d set", iAudioNumChannels);
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////
 //                            Private methods
 ////////////////////////////////////////////////////////////////////////////
 
@@ -750,8 +799,8 @@ PVMFStatus AndroidAudioInput::DoInit()
     LOGV("DoInit");
 
     //calculate time for a buffer to fill
-    iAudioNumChannels = 1;
-    iMicroSecondsPerDataEvent = (int32)(1000000/iAudioSamplingRate);
+    iMicroSecondsPerDataEvent = (int32)((1000000/iAudioSamplingRate) / iAudioNumChannels);
+    LOGV("AndroidAudioInput::DoInit() iMicroSecondsPerDataEvent %d", iMicroSecondsPerDataEvent);
 
     iDataEventCounter = 0;
 
@@ -764,8 +813,10 @@ PVMFStatus AndroidAudioInput::DoInit()
             iMediaBufferMemPool = NULL;
         }
         iMediaBufferMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (4));
-        if(!iMediaBufferMemPool)
+        if(!iMediaBufferMemPool) {
+            LOGV("AndroidAudioInput::DoInit() unable to create memory pool.  Return PVMFErrNoMemory.");
             OSCL_LEAVE(OsclErrNoMemory);
+        }
     );
     OSCL_FIRST_CATCH_ANY(err, return PVMFErrNoMemory);
 
@@ -809,6 +860,7 @@ PVMFStatus AndroidAudioInput::DoStart()
     return PVMFSuccess;
 }
 
+////////////////////////////////////////////////////////////////////////////
 int AndroidAudioInput::start_audin_thread_func(TOsclThreadFuncArg arg)
 {
     prctl(PR_SET_NAME, (unsigned long) "audio in", 0, 0, 0);
@@ -825,6 +877,7 @@ PVMFStatus AndroidAudioInput::DoPause()
     return PVMFSuccess;
 }
 
+////////////////////////////////////////////////////////////////////////////
 PVMFStatus AndroidAudioInput::DoReset()
 {
     LOGV("DoReset");
@@ -997,10 +1050,12 @@ int AndroidAudioInput::audin_thread_func() {
     iAudioThreadStartLock->lock();
 
     LOGV("create AudioRecord %p", this);
-    android::AudioRecord
-            * record = new android::AudioRecord(
-                    android::AudioRecord::DEFAULT_INPUT, iAudioSamplingRate,
-                    android::AudioSystem::PCM_16_BIT, iAudioNumChannels, 4*kBufferSize/iAudioNumChannels/sizeof(int16));
+    AudioRecord
+            * record = new AudioRecord(
+                    iAudioSource, iAudioSamplingRate,
+                    android::AudioSystem::PCM_16_BIT,
+                    iAudioNumChannels,
+                    4*kBufferSize/iAudioNumChannels/sizeof(int16));
     LOGV("AudioRecord created %p, this %p", record, this);
 
     status_t res = record->initCheck();
index 664c7c2..a31c568 100644 (file)
@@ -38,9 +38,6 @@
 #ifndef OSCL_VECTOR_H_INCLUDED
 #include "oscl_vector.h"
 #endif
-#ifndef PVLOGGER_H_INCLUDED
-#include "pvlogger.h"
-#endif
 #ifndef PVMI_MIO_CONTROL_H_INCLUDED
 #include "pvmi_mio_control.h"
 #endif
 
 namespace android {
 
+static const int32 DEFAULT_AUDIO_NUMBER_OF_CHANNELS = 1;
+static const int32 DEFAULT_AUDIO_SAMPLING_RATE = 8000;
+
+static const int32 MAX_AUDIO_SAMPLING_RATE = 96000; // In Hz
+static const int32 MIN_AUDIO_SAMPLING_RATE = 7350;  // In Hz
+
+static const int32 MAX_AUDIO_NUMBER_OF_CHANNELS = 2;
+static const int32 MIN_AUDIO_NUMBER_OF_CHANNELS = 1;
+
+
 class AndroidAudioInput;
 class Mutex;
 class Condition;
@@ -198,7 +205,7 @@ class AndroidAudioInput : public OsclTimerObject,
     public RefBase
 {
 public:
-    AndroidAudioInput();
+    AndroidAudioInput(uint32 audioSource);
     virtual ~AndroidAudioInput();
 
     // Pure virtuals from PvmiMIOControl
@@ -277,7 +284,14 @@ public:
      */
     int maxAmplitude();
 
+    /* Sets the input sampling rate */
+    bool setAudioSamplingRate(int32 iSamplingRate);
+
+    /* Set the input number of channels */
+    bool setAudioNumChannels(int32 iNumChannels);
+
 private:
+    AndroidAudioInput();
     void Run();
 
     int audin_thread_func();
@@ -366,9 +380,8 @@ private:
     OSCL_HeapString<OsclMemAllocator> iAudioFormatString;
     PVMFFormatType iAudioFormat;
     int32 iAudioNumChannels;
-    bool iAudioNumChannelsValid;
     int32 iAudioSamplingRate;
-    bool iAudioSamplingRateValid;
+    uint32 iAudioSource;
 
     int32 iFrameSize;
     int32 iDataEventCounter;
index 5d75bff..89c2a83 100644 (file)
@@ -926,6 +926,7 @@ PVMFStatus AndroidCameraInput::DoInit()
     }
     CameraParameters p(s);
     p.setPreviewSize(mFrameWidth, mFrameHeight);
+    p.setPreviewFrameRate(mFrameRate);
     s = p.flatten();
     if (mCamera->setParameters(s) != NO_ERROR) {
         LOGE("Failed to set camera(%p) parameters", mCamera.get());
index c7a4879..c51306d 100644 (file)
@@ -22,6 +22,7 @@
 #include <media/thread_init.h>
 #include <ui/ISurface.h>
 #include <ui/ICamera.h>
+#include <cutils/properties.h> // for property_get
 #include "authordriver.h"
 #include "pv_omxcore.h"
 #include <sys/prctl.h>
@@ -110,8 +111,12 @@ AuthorDriver::AuthorDriver()
     mVideoFrameRate((int)ANDROID_DEFAULT_FRAME_RATE),
     mVideoEncoder(VIDEO_ENCODER_DEFAULT),
     mOutputFormat(OUTPUT_FORMAT_DEFAULT),
-    mAudioEncoder(AUDIO_ENCODER_DEFAULT)
-      ,ifpOutput(NULL)
+    mAudioEncoder(AUDIO_ENCODER_DEFAULT),
+    mSamplingRate(0),
+    mNumberOfChannels(0),
+    mAudio_bitrate_setting(0),
+    mVideo_bitrate_setting(0),
+    ifpOutput(NULL)
 {
     mSyncSem = new OsclSemaphore();
     mSyncSem->Create();
@@ -300,26 +305,14 @@ void AuthorDriver::handleSetAudioSource(set_audio_source_command *ac)
 {
     int error = 0;
 
-    switch(ac->as) {
-    case AUDIO_SOURCE_DEFAULT:
-    case AUDIO_SOURCE_MIC:
-        mAudioInputMIO = new AndroidAudioInput();
-        if(mAudioInputMIO != NULL){
-            LOGV("create mio input audio");
-            mAudioNode = PvmfMediaInputNodeFactory::Create(static_cast<PvmiMIOControl *>(mAudioInputMIO.get()));
-            if(mAudioNode){
-                break;
-            }
-            else{
-            // do nothing, let it go in default case
-            }
-        }
-        else{
-        // do nothing, let it go in default case
+    mAudioInputMIO = new AndroidAudioInput(ac->as);
+    if (mAudioInputMIO != NULL) {
+        LOGV("create mio input audio");
+        mAudioNode = PvmfMediaInputNodeFactory::Create(static_cast<PvmiMIOControl *>(mAudioInputMIO.get()));
+        if (mAudioNode == NULL) {
+            commandFailed(ac);
+            return;
         }
-    default:
-        commandFailed(ac);
-        return;
     }
 
     OSCL_TRY(error, mAuthor->AddDataSource(*mAudioNode, ac));
@@ -362,23 +355,37 @@ void AuthorDriver::handleSetVideoSource(set_video_source_command *ac)
 void AuthorDriver::handleSetOutputFormat(set_output_format_command *ac)
 {
     int error = 0;
-    OSCL_HeapString<OsclMemAllocator> iComposerMimeType;
 
     if (ac->of == OUTPUT_FORMAT_DEFAULT) {
         ac->of = OUTPUT_FORMAT_THREE_GPP;
     }
 
+    OSCL_HeapString<OsclMemAllocator> mComposerMimeType;
+
     switch(ac->of) {
     case OUTPUT_FORMAT_THREE_GPP:
-        iComposerMimeType = "/x-pvmf/ff-mux/3gp";
+        mComposerMimeType = "/x-pvmf/ff-mux/3gp";
         break;
 
     case OUTPUT_FORMAT_MPEG_4:
-        iComposerMimeType = "/x-pvmf/ff-mux/mp4";
+        mComposerMimeType = "/x-pvmf/ff-mux/mp4";
+        break;
+
+    //case OUTPUT_FORMAT_RAW_AMR: //"duplicate case value" keep this to be backward compatible
+    case OUTPUT_FORMAT_AMR_NB:
+        mComposerMimeType = "/x-pvmf/ff-mux/amr-nb";
+        break;
+
+    case OUTPUT_FORMAT_AMR_WB:
+        mComposerMimeType = "/x-pvmf/ff-mux/amr-wb";
         break;
 
-    case OUTPUT_FORMAT_RAW_AMR:
-        iComposerMimeType = "/x-pvmf/ff-mux/amr-nb"; 
+    case OUTPUT_FORMAT_AAC_ADIF:
+        mComposerMimeType = "/x-pvmf/ff-mux/adif";
+        break;
+
+    case OUTPUT_FORMAT_AAC_ADTS:
+        mComposerMimeType = "/x-pvmf/ff-mux/adts";
         break;
 
     default:
@@ -389,7 +396,7 @@ void AuthorDriver::handleSetOutputFormat(set_output_format_command *ac)
 
     mOutputFormat = ac->of;
 
-    OSCL_TRY(error, mAuthor->SelectComposer(iComposerMimeType, mComposerConfig, ac));
+    OSCL_TRY(error, mAuthor->SelectComposer(mComposerMimeType, mComposerConfig, ac));
     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
 }
 
@@ -402,6 +409,8 @@ void AuthorDriver::media_track_added(status_t status, void *cookie)
 
 void AuthorDriver::handleSetAudioEncoder(set_audio_encoder_command *ac)
 {
+    LOGV("AuthorDriver::handleSetAudioEncoder(%d)", ac->ae);
+
     int error = 0;
     OSCL_HeapString<OsclMemAllocator> iAudioEncoderMimeType;
 
@@ -411,13 +420,118 @@ void AuthorDriver::handleSetAudioEncoder(set_audio_encoder_command *ac)
     switch(ac->ae) {
     case AUDIO_ENCODER_AMR_NB:
         iAudioEncoderMimeType = "/x-pvmf/audio/encode/amr-nb";
+        // AMR_NB only supports 8kHz sampling rate
+        if (mSamplingRate == 0)
+        {
+            // Sampling rate not set, use the default
+            mSamplingRate = 8000;
+        }
+        else if (mSamplingRate != 8000)
+        {
+            LOGE("Only valid sampling rate for AMR_NB is 8kHz.");
+            commandFailed(ac);
+            return;
+        }
+
+        // AMR_NB only supports mono (IE 1 channel)
+        if (mNumberOfChannels == 0)
+        {
+            // Number of channels not set, use the default
+            mNumberOfChannels = 1;
+        }
+        else if (mNumberOfChannels != 1)
+        {
+            LOGE("Only valid number of channels for ANR_NB is 1.");
+            commandFailed(ac);
+            return;
+        }
+        break;
+
+    case AUDIO_ENCODER_AMR_WB:
+        iAudioEncoderMimeType = "/x-pvmf/audio/encode/amr-wb";
+        // AMR_WB only supports 16kHz sampling rate
+        if (mSamplingRate == 0)
+        {
+            // Sampling rate not set, use the default
+            mSamplingRate = 16000;
+        }
+        else if (mSamplingRate != 16000)
+        {
+            LOGE("Only valid sampling rate for AMR_WB is 16kHz.");
+            commandFailed(ac);
+            return;
+        }
+
+        // AMR_WB only supports mono (IE 1 channel)
+        if (mNumberOfChannels == 0)
+        {
+            // Number of channels not set, use the default
+            mNumberOfChannels = 1;
+        }
+        else if (mNumberOfChannels != 1)
+        {
+            LOGE("Only valid number of channels for ANR_WB is 1.");
+            commandFailed(ac);
+            return;
+        }
         break;
 
+    case AUDIO_ENCODER_AAC:
+    case AUDIO_ENCODER_AAC_PLUS:
+    case AUDIO_ENCODER_EAAC_PLUS:
+        // Check the sampling rate
+        if (mSamplingRate == 0)
+        {
+            // No sampling rate set, use the default
+            mSamplingRate = DEFAULT_AUDIO_SAMPLING_RATE;
+        }
+        // Check the number of channels
+        if (mNumberOfChannels == 0)
+        {
+            // Number of channels not set, use the default
+            mNumberOfChannels = DEFAULT_AUDIO_NUMBER_OF_CHANNELS;
+        }
+
+        // Is file container type AAC-ADIF?
+        if(mOutputFormat == OUTPUT_FORMAT_AAC_ADIF)
+        {
+            // This is an audio only file container, set the correct encoder
+            iAudioEncoderMimeType = "/x-pvmf/audio/encode/aac/adif";
+        }
+        // AAC-ADTS?
+        else if (mOutputFormat == OUTPUT_FORMAT_AAC_ADTS)
+        {
+            // This is an audio only file container, set the correct encoder
+            iAudioEncoderMimeType = "/x-pvmf/audio/encode/aac/adts";
+        }
+        // else MPEG4 or 3GPP container ... use AAC-RAW
+        else
+        {
+            // AAC for mixed audio/video containers
+            iAudioEncoderMimeType = "/x-pvmf/audio/encode/X-MPEG4-AUDIO";
+        }
+        break;
     default:
         commandFailed(ac);
         return;
     }
 
+    LOGV("AuthorDriver::handleSetAudioEncoder() set %d %d \"%s\"", mSamplingRate, mNumberOfChannels, iAudioEncoderMimeType.get_cstr());
+
+    // Set the sampling rate and number of channels
+    if (!mAudioInputMIO->setAudioSamplingRate(mSamplingRate))
+    {
+        LOGE("Failed to set the sampling rate %d", mSamplingRate);
+        commandFailed(ac);
+        return;
+    }
+    if (!mAudioInputMIO->setAudioNumChannels(mNumberOfChannels))
+    {
+        LOGE("Failed to set the number of channels %d", mNumberOfChannels);
+        commandFailed(ac);
+        return;
+    }
+
     mAudioEncoder = ac->ae;
 
     OSCL_TRY(error, mAuthor->AddMediaTrack(*mAudioNode, iAudioEncoderMimeType, mSelectedComposer, mAudioEncoderConfig, ac));
@@ -451,6 +565,24 @@ void AuthorDriver::handleSetVideoEncoder(set_video_encoder_command *ac)
     }
 
     mVideoEncoder = ac->ve;
+    // Set video encoding frame rate and video frame size only when the
+    // video input MIO is set.
+    if (mVideoInputMIO) {
+        if (mVideoFrameRate == 0) {
+            mVideoFrameRate = DEFAULT_VIDEO_FRAME_RATE;
+        }
+        clipVideoFrameRate();
+        ((AndroidCameraInput *)mVideoInputMIO)->SetFrameRate(mVideoFrameRate);
+
+        if (mVideoWidth == 0) {
+            mVideoWidth = DEFAULT_VIDEO_WIDTH;
+        }
+        if (mVideoHeight == 0) {
+            mVideoHeight = DEFAULT_VIDEO_HEIGHT;
+        }
+        clipVideoFrameSize();
+        ((AndroidCameraInput *)mVideoInputMIO)->SetFrameSize(mVideoWidth, mVideoHeight);
+    }
 
     OSCL_TRY(error, mAuthor->AddMediaTrack(*mVideoNode, iVideoEncoderMimeType, mSelectedComposer, mVideoEncoderConfig, ac));
     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
@@ -464,22 +596,8 @@ void AuthorDriver::handleSetVideoSize(set_video_size_command *ac)
         return;
     }
 
-    // FIXME:
-    // Platform-specific and temporal workaround to prevent video size from being set too large
-    if (ac->width > ANDROID_MAX_ENCODED_FRAME_WIDTH) {
-        LOGW("Intended width(%d) exceeds the max allowed width(%d). Max width is used instead.", ac->width, ANDROID_MAX_ENCODED_FRAME_WIDTH);
-        mVideoWidth = ANDROID_MAX_ENCODED_FRAME_WIDTH;
-    } else {
-        mVideoWidth = ac->width;
-    }
-    if (ac->height > ANDROID_MAX_ENCODED_FRAME_HEIGHT) {
-        LOGW("Intended height(%d) exceeds the max allowed height(%d). Max height is used instead.", ac->height, ANDROID_MAX_ENCODED_FRAME_HEIGHT);
-        mVideoHeight = ANDROID_MAX_ENCODED_FRAME_HEIGHT;
-    } else {
-        mVideoHeight = ac->height;
-    }
-
-    ((AndroidCameraInput *)mVideoInputMIO)->SetFrameSize(mVideoWidth, mVideoHeight);
+    mVideoWidth = ac->width;
+    mVideoHeight = ac->height;
     FinishNonAsyncCommand(ac);
 }
 
@@ -490,17 +608,8 @@ void AuthorDriver::handleSetVideoFrameRate(set_video_frame_rate_command *ac)
         commandFailed(ac);
         return;
     }
-    
-    // FIXME:
-    // Platform-specific and temporal workaround to accept a reasonable frame rate range
-    if (ac->rate < ANDROID_MIN_FRAME_RATE_FPS) {
-    mVideoFrameRate = ANDROID_MIN_FRAME_RATE_FPS;
-    } else if (ac->rate > ANDROID_MAX_FRAME_RATE_FPS) {
-    mVideoFrameRate = ANDROID_MAX_FRAME_RATE_FPS;
-    } else {
+
     mVideoFrameRate = ac->rate;
-    }
-    ((AndroidCameraInput *)mVideoInputMIO)->SetFrameRate(mVideoFrameRate);
     FinishNonAsyncCommand(ac);
 }
 
@@ -538,20 +647,21 @@ void AuthorDriver::handleSetOutputFile(set_output_file_command *ac)
         LOGE("Ln %d fopen() error", __LINE__);
         goto exit;
     }
-    
-    if ( OUTPUT_FORMAT_RAW_AMR == mOutputFormat ) {
+
+    if (( OUTPUT_FORMAT_AMR_NB == mOutputFormat ) || ( OUTPUT_FORMAT_AMR_WB == mOutputFormat ) ||
+        ( OUTPUT_FORMAT_AAC_ADIF == mOutputFormat ) || ( OUTPUT_FORMAT_AAC_ADTS == mOutputFormat )) {
         PvmfFileOutputNodeConfigInterface *config = OSCL_DYNAMIC_CAST(PvmfFileOutputNodeConfigInterface*, mComposerConfig);
         if (!config) goto exit;
-        
+
         ret = config->SetOutputFileDescriptor(&OsclFileHandle(ifpOutput));
-    }  else if((OUTPUT_FORMAT_THREE_GPP == mOutputFormat) || (OUTPUT_FORMAT_MPEG_4 == mOutputFormat)) {
+    }  else if((OUTPUT_FORMAT_THREE_GPP == mOutputFormat) || (OUTPUT_FORMAT_MPEG_4 == mOutputFormat)){
         PVMp4FFCNClipConfigInterface *config = OSCL_DYNAMIC_CAST(PVMp4FFCNClipConfigInterface*, mComposerConfig);
         if (!config) goto exit;
-        
+
         config->SetPresentationTimescale(1000);
         ret = config->SetOutputFileDescriptor(&OsclFileHandle(ifpOutput));
     }
-    
+
 
 exit:
     if (ret == PVMFSuccess) {
@@ -611,6 +721,51 @@ PVMFStatus AuthorDriver::setMaxDurationOrFileSize(
     return ret;
 }
 
+PVMFStatus AuthorDriver::setParamAudioSamplingRate(int64_t aSamplingRate)
+{
+    // Do a rough check on the incoming sampling rate
+    if ((aSamplingRate < MIN_AUDIO_SAMPLING_RATE) || (aSamplingRate > MAX_AUDIO_SAMPLING_RATE))
+    {
+        LOGE("setParamAudioSamplingRate() invalid sampling rate.");
+        return PVMFErrArgument;
+    }
+
+    mSamplingRate = aSamplingRate;
+    LOGV("setParamAudioSamplingRate() set sampling rate %d", mSamplingRate);
+    return PVMFSuccess;
+}
+
+
+PVMFStatus AuthorDriver::setParamAudioNumberOfChannels(int64_t aNumberOfChannels)
+{
+    // Check the number of channels
+    if ((aNumberOfChannels < MIN_AUDIO_NUMBER_OF_CHANNELS) || (aNumberOfChannels > MAX_AUDIO_NUMBER_OF_CHANNELS))
+    {
+        LOGE("setParamAudioNumberOfChannels() invalid number of channels.");
+        return PVMFErrArgument;
+    }
+
+    mNumberOfChannels = aNumberOfChannels;
+    LOGV("setParamAudioNumberOfChannels() set num channels %d", mNumberOfChannels);
+    return PVMFSuccess;
+}
+
+PVMFStatus AuthorDriver::setParamAudioEncodingBitrate(int64_t aAudioBitrate)
+{
+    // Map the incoming audio bitrate settings
+    if ((aAudioBitrate < MIN_AUDIO_BITRATE_SETTING) || (aAudioBitrate > MAX_AUDIO_BITRATE_SETTING))
+    {
+        LOGE("setParamAudioEncodingBitrate() invalid audio bitrate.  Set call ignored.");
+        return PVMFErrArgument;
+    }
+
+    // Set the audio bitrate
+    mAudio_bitrate_setting = aAudioBitrate;
+
+    LOGV("setParamAudioEncodingBitrate() %d", mAudio_bitrate_setting);
+    return PVMFSuccess;
+}
+
 // Attempt to parse an int64 literal optionally surrounded by whitespace,
 // returns true on success, false otherwise.
 static bool safe_strtoi64(const char *s, int64 *val) {
@@ -664,11 +819,46 @@ PVMFStatus AuthorDriver::setParameter(
             return setMaxDurationOrFileSize(
                     max_filesize_bytes, false /* limit is filesize */);
         }
+    } else if (key == "audio-param-sampling-rate") {
+        int64_t sampling_rate;
+        if (safe_strtoi64(value.string(), &sampling_rate)) {
+            return setParamAudioSamplingRate(sampling_rate);
+        }
+    } else if (key == "audio-param-number-of-channels") {
+        int64_t number_of_channels;
+        if (safe_strtoi64(value.string(), &number_of_channels)) {
+            return setParamAudioNumberOfChannels(number_of_channels);
+        }
+    } else if (key == "audio-param-encoding-bitrate") {
+        int64_t audio_bitrate;
+        if (safe_strtoi64(value.string(), &audio_bitrate)) {
+            return setParamAudioEncodingBitrate(audio_bitrate);
+        }
+    } else if (key == "video-param-encoding-bitrate") {
+        int64_t video_bitrate;
+        if (safe_strtoi64(value.string(), &video_bitrate)) {
+            return setParamVideoEncodingBitrate(video_bitrate);
+        }
     }
 
+    // Return error if the key wasnt found
+    LOGE("AuthorDriver::setParameter() unrecognized key \"%s\"", key.string());
     return PVMFErrArgument;
 }
 
+PVMFStatus AuthorDriver::setParamVideoEncodingBitrate(int64_t aVideoBitrate)
+{
+    if (aVideoBitrate <= 0)
+    {
+        LOGE("setParamVideoEncodingBitrate() invalid video bitrate (%lld).  Set call ignored.", aVideoBitrate);
+        return PVMFErrArgument;
+    }
+
+    mVideo_bitrate_setting = aVideoBitrate;
+    LOGD("setParamVideoEncodingBitrate() %d", mVideo_bitrate_setting);
+    return PVMFSuccess;
+}
+
 // Applies the requested parameters, completes either successfully or stops
 // application of parameters upon encountering the first error, finishing the
 // transaction with the failure result of that initial failure.
@@ -721,12 +911,14 @@ void AuthorDriver::handleSetParameters(set_parameters_command *ac) {
     if (ret == PVMFSuccess) {
         FinishNonAsyncCommand(ac);
     } else {
-        LOGE("Ln %d handleSetParameters(%s) error", __LINE__, params);
+        LOGE("Ln %d handleSetParameters(\"%s\") error", __LINE__, params);
     commandFailed(ac);
     }
 }
+
 void AuthorDriver::handlePrepare(author_command *ac)
 {
+    LOGV("handlePrepare");
     int error = 0;
     OSCL_TRY(error, mAuthor->Init(ac));
     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
@@ -734,6 +926,7 @@ void AuthorDriver::handlePrepare(author_command *ac)
 
 void AuthorDriver::handleStart(author_command *ac)
 {
+    LOGV("handleStart");
     int error = 0;
     OSCL_TRY(error, mAuthor->Start(ac));
     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
@@ -875,11 +1068,17 @@ int AuthorDriver::authorThread()
     PendForExec();
 
     OsclExecScheduler *sched = OsclExecScheduler::Current();
-    sched->StartScheduler(mSyncSem);
+    error = OsclErrNone;
+    OSCL_TRY(error, sched->StartScheduler(mSyncSem));
+    OSCL_FIRST_CATCH_ANY(error,
+             // Some AO did a leave, log it
+             LOGE("Author Engine AO did a leave, error=%d", error)
+            );
+
     LOGV("Delete Author");
     PVAuthorEngineFactory::DeleteAuthor(mAuthor);
     mAuthor = NULL;
+
 
     // Let the destructor know that we're out
     mSyncStatus = OK;
@@ -909,11 +1108,215 @@ int AuthorDriver::authorThread()
     ed->mSyncSem->Signal();
 }
 
+// Backward compatible hardcoded video bit rate setting
+// These bit rate settings are from the original work with
+// QCOM's hardware encoders. Originally, anything above
+// 420000 bps is not stable, and default low quality bit
+// rate it set to 192000 bps. For those devices with
+// media capabilities specified as system properties, these
+// bit rate settings will not be used.
+static int setVideoBitrateHeuristically(int videoWidth)
+{
+    int bitrate_setting = 192000;
+    if (videoWidth >= 480) {
+        bitrate_setting = 420000;
+    } else if (videoWidth >= 352) {
+        bitrate_setting = 360000;
+    } else if (videoWidth >= 320) {
+        bitrate_setting = 320000;
+    }
+    return bitrate_setting;
+}
+
+
+// Returns true on success
+static bool getMinAndMaxValuesOfProperty(const char*propertyKey, int64& minValue, int64& maxValue)
+{
+    char value[PROPERTY_VALUE_MAX];
+    int rc = property_get(propertyKey, value, 0);
+    LOGV("property_get(): rc = %d, value=%s", rc, value);
+    if (rc > 0) {
+        char* b = strchr(value, ',');
+        if (b == 0) {  // A pair of values separated by ","?
+            return false;
+        } else {
+            String8 key(value, b - value);
+            if (!safe_strtoi64(key.string(), &minValue) || !safe_strtoi64(b + 1, &maxValue)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+// Maps the given encoder to a system property key
+// Returns true on success
+static bool getPropertyKeyForVideoEncoder(video_encoder encoder, char* name, size_t len)
+{
+    switch(encoder) {
+        case VIDEO_ENCODER_MPEG_4_SP:
+            strncpy(name, "ro.media.enc.vid.m4v.", len);
+            return true;
+        case VIDEO_ENCODER_H264:
+            strncpy(name, "ro.media.enc.vid.h264.", len);
+            return true;
+        case VIDEO_ENCODER_H263:
+            strncpy(name, "ro.media.enc.vid.h263.", len);
+            return true;
+        default:
+            LOGE("Failed to get system property key for video encoder(%d)", encoder);
+            return false;
+    }
+}
+
+// Retrieves the advertised video property range from system properties for the given encoder.
+// If the encoder is not found, or the video property is not listed as a system property,
+// default hardcoded min and max values will be used.
+static void getSupportedPropertyRange(video_encoder encoder, const char* property, int64& min, int64& max)
+{
+    char videoEncoderName[PROPERTY_KEY_MAX];
+    bool propertyKeyExists = getPropertyKeyForVideoEncoder(encoder, videoEncoderName, PROPERTY_KEY_MAX - 1);
+    if (propertyKeyExists) {
+        if ((strlen(videoEncoderName) + strlen(property) + 1) < PROPERTY_KEY_MAX) {  // Valid key length
+            strcat(videoEncoderName, property);
+        } else {
+            propertyKeyExists = false;
+        }
+    }
+    if (!propertyKeyExists || !getMinAndMaxValuesOfProperty(videoEncoderName, min, max)) {
+        if (strcmp(property, "bps") == 0) {
+            min = MIN_VIDEO_BITRATE_SETTING;
+            max = MAX_VIDEO_BITRATE_SETTING;
+        } else if (strcmp(property, "fps") == 0) {
+            min = ANDROID_MIN_FRAME_RATE_FPS;
+            max = ANDROID_MAX_FRAME_RATE_FPS;
+        } else if (strcmp(property, "width") == 0) {
+            min = ANDROID_MIN_ENCODED_FRAME_WIDTH;
+            max = ANDROID_MAX_ENCODED_FRAME_WIDTH;
+        } else if (strcmp(property, "height") == 0) {
+            min = ANDROID_MIN_ENCODED_FRAME_HEIGHT;
+            max = ANDROID_MAX_ENCODED_FRAME_HEIGHT;
+        } else {
+            LOGE("Unknown video property: %s", property);
+            min = max = 0;
+        }
+        LOGW("Use default video %s range [%lld %lld]", property, min, max);
+    }
+}
+
+static void getSupportedVideoBitRateRange(video_encoder encoder, int64& minBitRateBps, int64& maxBitRateBps)
+{
+    getSupportedPropertyRange(encoder, "bps", minBitRateBps, maxBitRateBps);
+}
+
+static void getSupportedVideoFrameRateRange(video_encoder encoder, int64& minFrameRateFps, int64& maxFrameRateFps)
+{
+    getSupportedPropertyRange(encoder, "fps", minFrameRateFps, maxFrameRateFps);
+}
+
+static void getSupportedVideoFrameWidthRange(video_encoder encoder, int64& minWidth, int64& maxWidth)
+{
+    getSupportedPropertyRange(encoder, "width", minWidth, maxWidth);
+}
+
+static void getSupportedVideoFrameHeightRange(video_encoder encoder, int64& minHeight, int64& maxHeight)
+{
+    getSupportedPropertyRange(encoder, "height", minHeight, maxHeight);
+}
+
+// Clips the intented video encoding rate so that it is
+// within the advertised support range. Logs a warning if
+// the intended bit rate is out of the range.
+void AuthorDriver::clipVideoBitrate()
+{
+    int64 minBitrate, maxBitrate;
+    getSupportedVideoBitRateRange(mVideoEncoder, minBitrate, maxBitrate);
+    if (mVideo_bitrate_setting < minBitrate) {
+        LOGW("Intended video encoding bit rate (%d bps) is too small and will be set to (%lld bps)", mVideo_bitrate_setting, minBitrate);
+        mVideo_bitrate_setting = minBitrate;
+    } else if (mVideo_bitrate_setting > maxBitrate) {
+        LOGW("Intended video encoding bit rate (%d bps) is too large and will be set to (%lld bps)", mVideo_bitrate_setting, maxBitrate);
+        mVideo_bitrate_setting = maxBitrate;
+    }
+}
+
+void AuthorDriver::clipVideoFrameRate()
+{
+    int64 minFrameRate, maxFrameRate;
+    getSupportedVideoFrameRateRange(mVideoEncoder, minFrameRate, maxFrameRate);
+    if (mVideoFrameRate < minFrameRate) {
+        LOGW("Intended video encoding frame rate (%d fps) is too small and will be set to (%lld fps)", mVideoFrameRate, minFrameRate);
+        mVideoFrameRate = minFrameRate;
+    } else if (mVideoFrameRate > maxFrameRate) {
+        LOGW("Intended video encoding frame rate (%d fps) is too large and will be set to (%lld fps)", mVideoFrameRate, maxFrameRate);
+        mVideoFrameRate = maxFrameRate;
+    }
+}
+
+void AuthorDriver::clipVideoFrameWidth()
+{
+    int64 minFrameWidth, maxFrameWidth;
+    getSupportedVideoFrameWidthRange(mVideoEncoder, minFrameWidth, maxFrameWidth);
+    if (mVideoWidth < minFrameWidth) {
+        LOGW("Intended video encoding frame width (%d) is too small and will be set to (%lld)", mVideoWidth, minFrameWidth);
+        mVideoWidth = minFrameWidth;
+    } else if (mVideoWidth > maxFrameWidth) {
+        LOGW("Intended video encoding frame width (%d) is too large and will be set to (%lld)", mVideoWidth, maxFrameWidth);
+        mVideoWidth = maxFrameWidth;
+    }
+}
+
+void AuthorDriver::clipVideoFrameHeight()
+{
+    int64 minFrameHeight, maxFrameHeight;
+    getSupportedVideoFrameHeightRange(mVideoEncoder, minFrameHeight, maxFrameHeight);
+    if (mVideoHeight < minFrameHeight) {
+        LOGW("Intended video encoding frame height (%d) is too small and will be set to (%lld)", mVideoHeight, minFrameHeight);
+        mVideoHeight = minFrameHeight;
+    } else if (mVideoHeight > maxFrameHeight) {
+        LOGW("Intended video encoding frame height (%d) is too large and will be set to (%lld)", mVideoHeight, maxFrameHeight);
+        mVideoHeight = maxFrameHeight;
+    }
+}
+
+void AuthorDriver::clipVideoFrameSize()
+{
+    clipVideoFrameWidth();
+    clipVideoFrameHeight();
+}
+
+void AuthorDriver::clipAACAudioBitrate()
+{
+    /*  ISO-IEC-13818-7 "Information technology.  Generic coding of moving
+     *   pictures and associated audio information.  Part 7: Advanced Audio
+     *   Coding (AAC)" section 8.2.2.3 defines a formula for the max audio
+     *   bitrate based on the audio sampling rate.
+     *   6144 (bit/block) / 1024 (samples/block) * sampling_freq * number_of_channels
+     *
+     *  This method is to calculate the max audio bitrate and clip the desired audio
+     *   bitrate if it exceeds its max.
+     */
+
+    int32 calculated_audio_bitrate = 6 * mSamplingRate * mNumberOfChannels;
+    if ((calculated_audio_bitrate > 0) &&
+        (mAudio_bitrate_setting > calculated_audio_bitrate))
+    {
+        // Clip the bitrate setting
+        LOGW("Intended audio bitrate (%d) exceeds max bitrate for sampling rate (%d).  Setting audio bitrate to its calculated max (%d)", mAudio_bitrate_setting, mSamplingRate, calculated_audio_bitrate);
+        mAudio_bitrate_setting = calculated_audio_bitrate;
+    }
+}
+
 void AuthorDriver::CommandCompleted(const PVCmdResponse& aResponse)
 {
     author_command *ac = (author_command *)aResponse.GetContext();
     status_t s = aResponse.GetCmdStatus();
-    LOGV("Command (%d) completed with status(%d)", ac->which, s);
+    LOGV("Command (%d) completed with status(%d)", ac? ac->which: -1, s);
+    if (ac == NULL) {
+        LOGE("CommandCompleted: Error - null author command!");
+        return;
+    }
 
     if (ac->which == AUTHOR_SET_OUTPUT_FORMAT) {
         mSelectedComposer = aResponse.GetResponseData();
@@ -921,24 +1324,19 @@ void AuthorDriver::CommandCompleted(const PVCmdResponse& aResponse)
 
     if (ac->which == AUTHOR_SET_VIDEO_ENCODER) {
         switch(mVideoEncoder) {
-        case VIDEO_ENCODER_H263: 
+        case VIDEO_ENCODER_H263:
         case VIDEO_ENCODER_MPEG_4_SP:
         case VIDEO_ENCODER_H264: {
             PVMp4H263EncExtensionInterface *config = OSCL_STATIC_CAST(PVMp4H263EncExtensionInterface*,
                                                                       mVideoEncoderConfig);
-            // TODO:
-            // fix the hardcoded bit rate settings.
             if (config) {
-                int bitrate_setting = 192000;
-                if (mVideoWidth >= 480) {
-                    bitrate_setting = 420000; // unstable
-                } else if (mVideoWidth >= 352) {
-                    bitrate_setting = 360000;
-                } else if (mVideoWidth >= 320) {
-                    bitrate_setting = 320000;
+                if (mVideo_bitrate_setting == 0) {
+                    mVideo_bitrate_setting = setVideoBitrateHeuristically(mVideoWidth);
+                    LOGW("Video encoding bit rate is set to %d bps", mVideo_bitrate_setting);
                 }
+                clipVideoBitrate();
                 config->SetNumLayers(1);
-                config->SetOutputBitRate(0, bitrate_setting);
+                config->SetOutputBitRate(0, mVideo_bitrate_setting);
                 config->SetOutputFrameSize(0, mVideoWidth, mVideoHeight);
                 config->SetOutputFrameRate(0, mVideoFrameRate);
                 config->SetIFrameInterval(ANDROID_DEFAULT_I_FRAME_INTERVAL);
@@ -951,22 +1349,64 @@ void AuthorDriver::CommandCompleted(const PVCmdResponse& aResponse)
     }
 
     if (ac->which == AUTHOR_SET_AUDIO_ENCODER) {
-        switch(mAudioEncoder) {
-            case AUDIO_ENCODER_AMR_NB: 
-                {
-                    PVAudioEncExtensionInterface *config = OSCL_STATIC_CAST(PVAudioEncExtensionInterface *,
-                            mAudioEncoderConfig);
-                    if (config) {
+        // Perform the cast to get the audio config interface
+        PVAudioEncExtensionInterface *config = OSCL_STATIC_CAST(PVAudioEncExtensionInterface*,
+                                                                mAudioEncoderConfig);
+
+        if (config)
+        {
+            switch(mAudioEncoder) {
+                case AUDIO_ENCODER_AMR_NB:
+                case AUDIO_ENCODER_AMR_WB:
+                    {
+                        // Map the audio bitrate to an AMR discreet bitrate
+                        PVMF_GSMAMR_Rate mAMRBitrate;
+                        if(!MapAMRBitrate(mAudio_bitrate_setting, mAMRBitrate)) {
+                            LOGE("Failed to map the audio bitrate to an AMR bitrate!  Using the defaults.");
+                            if (mAudioEncoder == AUDIO_ENCODER_AMR_NB) {
+                                mAMRBitrate = DEFAULT_AMR_NARROW_BAND_BITRATE_SETTING;
+                            }
+                            else { // Else use the default wideband setting
+                               mAMRBitrate = DEFAULT_AMR_WIDE_BAND_BITRATE_SETTING;
+                            }
+                        }
+                        config->SetOutputBitRate(mAMRBitrate);
                         config->SetMaxNumOutputFramesPerBuffer(10);
-                        config->SetOutputBitRate(GSM_AMR_5_15); // 5150 bps XXX
                     }
-                } 
-                break;
+                    break;
 
-            default:
-                break;
-        }
-    }
+                case AUDIO_ENCODER_AAC:
+                case AUDIO_ENCODER_AAC_PLUS:
+                case AUDIO_ENCODER_EAAC_PLUS:
+                    {
+                        if (mAudio_bitrate_setting == 0) {
+                            // Audio bitrate wasnt set, use the default
+                            mAudio_bitrate_setting = DEFAULT_AUDIO_BITRATE_SETTING;
+                        }
+                        clipAACAudioBitrate();
+                        config->SetOutputBitRate(mAudio_bitrate_setting);
+
+                        // Set AAC profile level
+                        if (mAudioEncoder == AUDIO_ENCODER_AAC_PLUS)
+                        {
+                            config->SetOutputAacProfile(PV_AAC_ENC_HE);
+                        }
+                        else if (mAudioEncoder == AUDIO_ENCODER_EAAC_PLUS)
+                        {
+                            config->SetOutputAacProfile(PV_AAC_ENC_HE_PS);
+                        }
+                        else
+                        {
+                            // For all others
+                            config->SetOutputAacProfile(PV_AAC_ENC_LC);
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            } // End switch(mAudioEncoder)
+        } // End if (config)
+    } // End if (ac->which == AUTHOR_SET_AUDIO_ENCODER)
 
     // delete video and/or audio nodes to prevent memory leakage
     // when an authroing session is reused
@@ -975,7 +1415,7 @@ void AuthorDriver::CommandCompleted(const PVCmdResponse& aResponse)
         doCleanUp();
     }
 
-    // Translate the PVMF error codes into Android ones 
+    // Translate the PVMF error codes into Android ones
     switch(s) {
         case PVMFSuccess: s = android::OK; break;
         case PVMFPending: *(char *)0 = 0; break; /* XXX assert */
@@ -988,6 +1428,39 @@ void AuthorDriver::CommandCompleted(const PVCmdResponse& aResponse)
     delete ac;
 }
 
+bool AuthorDriver::MapAMRBitrate(int32 aAudioBitrate, PVMF_GSMAMR_Rate &anAMRBitrate)
+{
+    if ((mAudioEncoder != AUDIO_ENCODER_AMR_NB) &&
+            (mAudioEncoder != AUDIO_ENCODER_AMR_WB)) {
+        LOGE("AuthorDriver::MapAMRBitrate() encoder type is not AMR.");
+        return false;
+    }
+
+    // Default to AMR_NB
+    uint32 AMR_Index = 0;
+
+    // Is this ARM_WB?
+    if (mAudioEncoder == AUDIO_ENCODER_AMR_WB)
+    {
+        // Use the other side of the array
+        AMR_Index = 1;
+    }
+
+    uint32 jj;
+    for (jj = 0; jj < AMR_BITRATE_MAX_NUMBER_OF_ROWS; jj++)
+    {
+        if (aAudioBitrate < AMR_BITRATE_MAPPING_ARRAY[jj][AMR_Index].bitrate)
+        {
+            // Found a match!
+            anAMRBitrate = AMR_BITRATE_MAPPING_ARRAY[jj][AMR_Index].actual;
+            return true;
+        }
+    }
+
+    // Failed to map the bitrate.  Return false and use the defaults.
+    return false;
+}
+
 void AuthorDriver::HandleErrorEvent(const PVAsyncErrorEvent& aEvent)
 {
     LOGE("HandleErrorEvent(%d)", aEvent.GetEventType());
index b695fc6..0492703 100644 (file)
 // FIXME:
 // Platform-specic and temporal workaround to prevent video size
 // from being set too large
+
 #define ANDROID_MAX_ENCODED_FRAME_WIDTH            352
 #define ANDROID_MAX_ENCODED_FRAME_HEIGHT           288
+#define ANDROID_MIN_ENCODED_FRAME_WIDTH            176
+#define ANDROID_MIN_ENCODED_FRAME_HEIGHT           144
 
 #define ANDROID_MIN_FRAME_RATE_FPS                 5
 #define ANDROID_MAX_FRAME_RATE_FPS                 20
 
+static const int32 DEFAULT_VIDEO_FRAME_RATE  = 20;
+static const int32 DEFAULT_VIDEO_WIDTH       = 176;
+static const int32 DEFAULT_VIDEO_HEIGHT      = 144;
+
+static const int32 MIN_VIDEO_BITRATE_SETTING = 192000;
+static const int32 MAX_VIDEO_BITRATE_SETTING = 420000;
+static const int32 MAX_AUDIO_BITRATE_SETTING = 320000; // Max bitrate??
+static const int32 MIN_AUDIO_BITRATE_SETTING = 1;      // Min bitrate??
+static const int32 DEFAULT_AUDIO_BITRATE_SETTING = 64000; // Default for all the other audio
+static const PVMF_GSMAMR_Rate DEFAULT_AMR_NARROW_BAND_BITRATE_SETTING = GSM_AMR_12_2;
+static const PVMF_GSMAMR_Rate DEFAULT_AMR_WIDE_BAND_BITRATE_SETTING = GSM_AMR_23_85;
+
+typedef struct AMR_BITRATE_MAPPING
+{
+   int32 bitrate;
+   PVMF_GSMAMR_Rate actual;
+} AMR_BITRATE_MAPPING;
+
+static const uint32 AMR_BITRATE_MAX_NUMBER_OF_ROWS = 10;
+static const AMR_BITRATE_MAPPING AMR_BITRATE_MAPPING_ARRAY[AMR_BITRATE_MAX_NUMBER_OF_ROWS][2] = {
+    {{1,DEFAULT_AMR_NARROW_BAND_BITRATE_SETTING}, {1,    DEFAULT_AMR_WIDE_BAND_BITRATE_SETTING}},  // default values
+    {{4950,                        GSM_AMR_4_75}, {7725,                          GSM_AMR_6_60}},
+    {{5525,                        GSM_AMR_5_15}, {10750,                         GSM_AMR_8_85}},
+    {{6300,                        GSM_AMR_5_90}, {13450,                        GSM_AMR_12_65}},
+    {{7050,                        GSM_AMR_6_70}, {15050,                        GSM_AMR_14_25}},
+    {{7625,                        GSM_AMR_7_40}, {17050,                        GSM_AMR_15_85}},
+    {{9075,                        GSM_AMR_7_95}, {19050,                        GSM_AMR_18_25}},
+    {{11200,                       GSM_AMR_10_2}, {21450,                        GSM_AMR_19_85}},
+   {{(MAX_AUDIO_BITRATE_SETTING+1),GSM_AMR_12_2}, {23450,                        GSM_AMR_23_05}},
+   {{(MAX_AUDIO_BITRATE_SETTING+1),GSM_AMR_12_2},{(MAX_AUDIO_BITRATE_SETTING+1), GSM_AMR_23_85}}};
+
 namespace android {
 
 template<class DestructClass>
@@ -276,8 +310,34 @@ private:
     // milliseconds, otherwise "limit" holds the maximum filesize in bytes.
     PVMFStatus setMaxDurationOrFileSize(int64_t limit, bool limit_is_duration);
 
+    // Used to set the sampling rate of the audio source
+    PVMFStatus setParamAudioSamplingRate(int64_t aSamplingRate);
+
+    // Used to set the number of channels of the audio source
+    PVMFStatus setParamAudioNumberOfChannels(int64_t aNumberOfChannels);
+
+    // Used for setting the audio encoding bitrate
+    PVMFStatus setParamAudioEncodingBitrate(int64_t aAudioBitrate);
+
     PVMFStatus setParameter(const String8 &key, const String8 &value);
 
+    // Has no effect if called after video encoder is set
+    PVMFStatus setParamVideoEncodingBitrate(int64_t aVideoBitrate);
+
+    // Clips the intended video encoding bit rate, frame rate, frame size
+    // (width and height) so that it is within the supported range.
+    void clipVideoBitrate();
+    void clipVideoFrameRate();
+    void clipVideoFrameSize();
+    void clipVideoFrameWidth();
+    void clipVideoFrameHeight();
+
+    // Clips the intended AAC audio bitrate so that it is in the supported range
+    void clipAACAudioBitrate();
+
+    // Used to map the incoming bitrate to the closest AMR bitrate
+    bool MapAMRBitrate(int32 aAudioBitrate, PVMF_GSMAMR_Rate &anAMRBitrate);
+
     PVAuthorEngineInterface    *mAuthor;
 
     PvmiMIOControl           *mVideoInputMIO;
@@ -312,6 +372,11 @@ private:
     sp<ICamera>             mCamera;
     sp<IMediaPlayerClient>  mListener;
 
+    int32            mSamplingRate;
+    int32            mNumberOfChannels;
+    int32            mAudio_bitrate_setting;
+    int32            mVideo_bitrate_setting;
+
     FILE*       ifpOutput;
 };
 
index a4746ed..583d033 100644 (file)
@@ -21,7 +21,7 @@
 // This header file is automatically generated at build-time
 // *** OFFICIAL RELEASE INFO -- Will not auto update
 
-#define PV2WAY_ENGINE_SDKINFO_LABEL "971436"
+#define PV2WAY_ENGINE_SDKINFO_LABEL "971968"
 #define PV2WAY_ENGINE_SDKINFO_DATE 0x20090918
 
 #endif //PV_2WAY_SDKINFO_H_INCLUDED
index 33fafbf..330a48b 100644 (file)
@@ -21,7 +21,7 @@
 // This header file is automatically generated at build-time
 // *** OFFICIAL RELEASE INFO -- Will not auto update
 
-#define PVAUTHOR_ENGINE_SDKINFO_LABEL "971436"
+#define PVAUTHOR_ENGINE_SDKINFO_LABEL "971968"
 #define PVAUTHOR_ENGINE_SDKINFO_DATE 0x20090918
 
 #endif //PV_AUTHOR_SDKINFO_H_INCLUDED
index 7c066f5..2fd58ae 100644 (file)
@@ -21,7 +21,7 @@
 // This header file is automatically generated at build-time
 // *** OFFICIAL RELEASE INFO -- Will not auto update
 
-#define PVPLAYER_ENGINE_SDKINFO_LABEL "971436"
+#define PVPLAYER_ENGINE_SDKINFO_LABEL "971968"
 #define PVPLAYER_ENGINE_SDKINFO_DATE 0x20090918
 
 #endif //PV_PLAYER_SDKINFO_H_INCLUDED