Home | History | Annotate | Download | only in author
      1 /*
      2  * Copyright (C) 2008, The Android Open Source Project
      3  * Copyright (C) 2008 HTC Inc.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 //#define LOG_NDEBUG 0
     19 #define LOG_TAG "AuthorDriver"
     20 
     21 #include <unistd.h>
     22 #include <media/thread_init.h>
     23 #include <media/MediaProfiles.h>
     24 #include <surfaceflinger/ISurface.h>
     25 #include <camera/ICamera.h>
     26 #include "authordriver.h"
     27 #include "pv_omxcore.h"
     28 #include <sys/prctl.h>
     29 #include "pvmf_composer_size_and_duration.h"
     30 #include "pvmf_duration_infomessage.h"
     31 #include "android_camera_input.h"
     32 
     33 using namespace android;
     34 
     35 AuthorDriverWrapper::AuthorDriverWrapper()
     36 {
     37     mAuthorDriver = new AuthorDriver();
     38 }
     39 
     40 void AuthorDriverWrapper::resetAndClose()
     41 {
     42     LOGV("resetAndClose");
     43     mAuthorDriver->enqueueCommand(new author_command(AUTHOR_RESET), NULL, NULL);
     44     mAuthorDriver->enqueueCommand(new author_command(AUTHOR_REMOVE_VIDEO_SOURCE), NULL, NULL);
     45     mAuthorDriver->enqueueCommand(new author_command(AUTHOR_REMOVE_AUDIO_SOURCE), NULL, NULL);
     46     mAuthorDriver->enqueueCommand(new author_command(AUTHOR_CLOSE), NULL, NULL);
     47 }
     48 
     49 AuthorDriverWrapper::~AuthorDriverWrapper()
     50 {
     51     LOGV("Destructor");
     52     if (mAuthorDriver) {
     53         // set the authoring engine to the IDLE state.
     54         PVAEState state = mAuthorDriver->getAuthorEngineState();
     55         LOGV("state(%d)", state);
     56         switch (state) {
     57         case PVAE_STATE_IDLE:
     58             break;
     59 
     60         case PVAE_STATE_RECORDING:
     61             mAuthorDriver->enqueueCommand(new author_command(AUTHOR_STOP),  NULL, NULL);
     62             resetAndClose();
     63             break;
     64 
     65         default:
     66             resetAndClose();
     67             break;
     68         }
     69 
     70         // now it is safe to quit.
     71         author_command *ac = new author_command(AUTHOR_QUIT);
     72         enqueueCommand(ac, NULL, NULL); // will wait on mSyncSem, signaled by author thread
     73         delete ac; // have to delete this manually because CommandCompleted won't be called
     74     }
     75 }
     76 
     77 status_t AuthorDriverWrapper::getMaxAmplitude(int *max)
     78 {
     79     if (mAuthorDriver) {
     80         return mAuthorDriver->getMaxAmplitude(max);
     81     }
     82     return NO_INIT;
     83 }
     84 
     85 status_t AuthorDriverWrapper::enqueueCommand(author_command *ac, media_completion_f comp, void *cookie)
     86 {
     87     if (mAuthorDriver) {
     88         return mAuthorDriver->enqueueCommand(ac, comp, cookie);
     89     }
     90     return NO_INIT;
     91 }
     92 
     93 status_t AuthorDriverWrapper::setListener(const sp<IMediaPlayerClient>& listener) {
     94     if (mAuthorDriver) {
     95     return mAuthorDriver->setListener(listener);
     96     }
     97     return NO_INIT;
     98 }
     99 
    100 AuthorDriver::AuthorDriver()
    101     : OsclActiveObject(OsclActiveObject::EPriorityNominal, "AuthorDriver"),
    102     mAuthor(NULL),
    103     mVideoInputMIO(NULL),
    104     mVideoNode(NULL),
    105     mAudioNode(NULL),
    106     mSelectedComposer(NULL),
    107     mComposerConfig(NULL),
    108     mVideoEncoderConfig(NULL),
    109     mAudioEncoderConfig(NULL),
    110     mVideoWidth(ANDROID_DEFAULT_FRAME_WIDTH),
    111     mVideoHeight(ANDROID_DEFAULT_FRAME_HEIGHT),
    112     mVideoFrameRate((int)ANDROID_DEFAULT_FRAME_RATE),
    113     mVideoEncoder(VIDEO_ENCODER_DEFAULT),
    114     mOutputFormat(OUTPUT_FORMAT_DEFAULT),
    115     mAudioEncoder(AUDIO_ENCODER_DEFAULT),
    116     mSamplingRate(0),
    117     mNumberOfChannels(0),
    118     mAudio_bitrate_setting(0),
    119     mVideo_bitrate_setting(0),
    120     ifpOutput(NULL)
    121 {
    122     mMediaProfiles = MediaProfiles::getInstance();
    123     mSyncSem = new OsclSemaphore();
    124     mSyncSem->Create();
    125 
    126     createThread(AuthorDriver::startAuthorThread, this);
    127     // mSyncSem will be signaled when the scheduler has started
    128     mSyncSem->Wait();
    129 }
    130 
    131 AuthorDriver::~AuthorDriver()
    132 {
    133 }
    134 
    135 author_command *AuthorDriver::dequeueCommand()
    136 {
    137     author_command *ac;
    138     mQueueLock.lock();
    139 
    140     // XXX should we assert here?
    141     if (mCommandQueue.empty()) {
    142         PendForExec();
    143         mQueueLock.unlock();
    144         return NULL;
    145     }
    146 
    147     ac = *(--mCommandQueue.end());
    148     mCommandQueue.erase(--mCommandQueue.end());
    149     if (mCommandQueue.size() > 0) {
    150         RunIfNotReady();
    151     } else {
    152         PendForExec();
    153     }
    154     mQueueLock.unlock();
    155 
    156     return ac;
    157 }
    158 
    159 status_t AuthorDriver::enqueueCommand(author_command *ac, media_completion_f comp, void *cookie)
    160 {
    161     if (mAuthor == NULL) {
    162         return NO_INIT;
    163     }
    164     // If the user didn't specify a completion callback, we
    165     // are running in synchronous mode.
    166     if (comp == NULL) {
    167         ac->comp = AuthorDriver::syncCompletion;
    168         ac->cookie = this;
    169     } else {
    170         ac->comp = comp;
    171         ac->cookie = cookie;
    172     }
    173 
    174     // Add the command to the queue.
    175     mQueueLock.lock();
    176     mCommandQueue.push_front(ac);
    177 
    178     // make a copy of this semaphore for special handling of the AUTHOR_QUIT command
    179     OsclSemaphore *syncsemcopy = mSyncSem;
    180     // make a copy of ac->which, since ac will be deleted by the standard completion function
    181     author_command_type whichcopy = ac->which;
    182 
    183     // Wake up the author thread so it can dequeue the command.
    184     if (mCommandQueue.size() == 1) {
    185         PendComplete(OSCL_REQUEST_ERR_NONE);
    186     }
    187     mQueueLock.unlock();
    188     // If we are in synchronous mode, wait for completion.
    189     if (syncsemcopy) {
    190         syncsemcopy->Wait();
    191         if (whichcopy == AUTHOR_QUIT) {
    192             syncsemcopy->Close();
    193             delete syncsemcopy;
    194             return 0;
    195         }
    196         return mSyncStatus;
    197     }
    198 
    199     return OK;
    200 }
    201 
    202 void AuthorDriver::FinishNonAsyncCommand(author_command *ac)
    203 {
    204     ac->comp(0, ac->cookie); // this signals the semaphore for synchronous calls
    205     delete ac;
    206 }
    207 
    208 // The OSCL scheduler calls this when we get to run (this should happen only
    209 // when a command has been enqueued for us).
    210 void AuthorDriver::Run()
    211 {
    212     author_command *ac = dequeueCommand();
    213     if (ac == NULL) {
    214     LOGE("Unexpected NULL command");
    215     OSCL_LEAVE(PVMFErrArgument);
    216         // assert?
    217         return;
    218     }
    219 
    220     switch(ac->which) {
    221     case AUTHOR_INIT:
    222         handleInit(ac);
    223         break;
    224 
    225     case AUTHOR_SET_AUDIO_SOURCE:
    226         handleSetAudioSource((set_audio_source_command *)ac);
    227         break;
    228 
    229     case AUTHOR_SET_VIDEO_SOURCE:
    230         handleSetVideoSource((set_video_source_command *)ac);
    231         break;
    232 
    233     case AUTHOR_SET_OUTPUT_FORMAT:
    234         handleSetOutputFormat((set_output_format_command *)ac);
    235         break;
    236 
    237     case AUTHOR_SET_AUDIO_ENCODER:
    238         handleSetAudioEncoder((set_audio_encoder_command *)ac);
    239         break;
    240 
    241     case AUTHOR_SET_VIDEO_ENCODER:
    242         handleSetVideoEncoder((set_video_encoder_command *)ac);
    243         break;
    244 
    245     case AUTHOR_SET_VIDEO_SIZE:
    246         handleSetVideoSize((set_video_size_command *)ac);
    247         return;
    248 
    249     case AUTHOR_SET_VIDEO_FRAME_RATE:
    250         handleSetVideoFrameRate((set_video_frame_rate_command *)ac);
    251         return;
    252 
    253     case AUTHOR_SET_PREVIEW_SURFACE:
    254         handleSetPreviewSurface((set_preview_surface_command *)ac);
    255         return;
    256 
    257     case AUTHOR_SET_CAMERA:
    258         handleSetCamera((set_camera_command *)ac);
    259         return;
    260 
    261     case AUTHOR_SET_OUTPUT_FILE:
    262         handleSetOutputFile((set_output_file_command *)ac);
    263         return;
    264 
    265     case AUTHOR_SET_PARAMETERS:
    266         handleSetParameters((set_parameters_command *)ac);
    267         return;
    268 
    269     case AUTHOR_REMOVE_VIDEO_SOURCE:
    270         handleRemoveVideoSource(ac);
    271         return;
    272 
    273     case AUTHOR_REMOVE_AUDIO_SOURCE:
    274         handleRemoveAudioSource(ac);
    275         return;
    276 
    277     case AUTHOR_PREPARE: handlePrepare(ac); break;
    278     case AUTHOR_START: handleStart(ac); break;
    279     case AUTHOR_STOP: handleStop(ac); break;
    280     case AUTHOR_CLOSE: handleClose(ac); break;
    281     case AUTHOR_RESET: handleReset(ac); break;
    282     case AUTHOR_QUIT: handleQuit(ac); return;
    283 
    284     default:
    285     LOGE("Unknown author command: %d", ac->which);
    286     OSCL_LEAVE(PVMFErrArgument);
    287         break;
    288     }
    289 
    290  }
    291 
    292 void AuthorDriver::commandFailed(author_command *ac)
    293 {
    294     LOGE("Command (%d) failed", ac->which);
    295     ac->comp(UNKNOWN_ERROR, ac->cookie);
    296     delete ac;
    297 }
    298 
    299 void AuthorDriver::handleInit(author_command *ac)
    300 {
    301     int error = 0;
    302     OSCL_TRY(error, mAuthor->Open(ac));
    303     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    304 }
    305 
    306 void AuthorDriver::handleSetAudioSource(set_audio_source_command *ac)
    307 {
    308     int error = 0;
    309 
    310     mAudioInputMIO = new AndroidAudioInput(ac->as);
    311     if (mAudioInputMIO != NULL) {
    312         LOGV("create mio input audio");
    313         mAudioNode = PvmfMediaInputNodeFactory::Create(static_cast<PvmiMIOControl *>(mAudioInputMIO.get()));
    314         if (mAudioNode == NULL) {
    315             commandFailed(ac);
    316             return;
    317         }
    318         // force audio source to camcorder when recording video
    319         if (mVideoInputMIO != NULL) {
    320             mAudioInputMIO->setAudioSource(AUDIO_SOURCE_CAMCORDER);
    321         }
    322     }
    323 
    324     OSCL_TRY(error, mAuthor->AddDataSource(*mAudioNode, ac));
    325     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    326 }
    327 
    328 void AuthorDriver::handleSetVideoSource(set_video_source_command *ac)
    329 {
    330     int error = 0;
    331 
    332     switch(ac->vs) {
    333     case VIDEO_SOURCE_DEFAULT:
    334     case VIDEO_SOURCE_CAMERA: {
    335         AndroidCameraInput* cameraInput = new AndroidCameraInput();
    336         if (cameraInput) {
    337             LOGV("create mio input video");
    338             mVideoNode = PvmfMediaInputNodeFactory::Create(cameraInput);
    339             if (mVideoNode) {
    340                 // pass in the application supplied camera object
    341                 if (mCamera == 0 ||
    342                     (mCamera != 0 && cameraInput->SetCamera(mCamera) == PVMFSuccess)) {
    343                     mVideoInputMIO = cameraInput;
    344                     // force audio source to camcorder when recording video
    345                     if (mAudioInputMIO != NULL) {
    346                         mAudioInputMIO->setAudioSource(AUDIO_SOURCE_CAMCORDER);
    347                     }
    348                     break;
    349                 }
    350             }
    351             delete cameraInput;
    352         }
    353         commandFailed(ac);
    354         return;
    355     }
    356     default:
    357         commandFailed(ac);
    358         return;
    359     }
    360 
    361     OSCL_TRY(error, mAuthor->AddDataSource(*mVideoNode, ac));
    362     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    363 }
    364 
    365 void AuthorDriver::handleSetOutputFormat(set_output_format_command *ac)
    366 {
    367     int error = 0;
    368 
    369     if (ac->of == OUTPUT_FORMAT_DEFAULT) {
    370         ac->of = OUTPUT_FORMAT_THREE_GPP;
    371     }
    372 
    373     OSCL_HeapString<OsclMemAllocator> mComposerMimeType;
    374 
    375     switch(ac->of) {
    376     case OUTPUT_FORMAT_THREE_GPP:
    377         mComposerMimeType = "/x-pvmf/ff-mux/3gp";
    378         break;
    379 
    380     case OUTPUT_FORMAT_MPEG_4:
    381         mComposerMimeType = "/x-pvmf/ff-mux/mp4";
    382         break;
    383 
    384     //case OUTPUT_FORMAT_RAW_AMR: //"duplicate case value" keep this to be backward compatible
    385     case OUTPUT_FORMAT_AMR_NB:
    386         mComposerMimeType = "/x-pvmf/ff-mux/amr-nb";
    387         break;
    388 
    389     case OUTPUT_FORMAT_AMR_WB:
    390         mComposerMimeType = "/x-pvmf/ff-mux/amr-wb";
    391         break;
    392 
    393     case OUTPUT_FORMAT_AAC_ADIF:
    394         mComposerMimeType = "/x-pvmf/ff-mux/adif";
    395         break;
    396 
    397     case OUTPUT_FORMAT_AAC_ADTS:
    398         mComposerMimeType = "/x-pvmf/ff-mux/adts";
    399         break;
    400 
    401     default:
    402         LOGE("Ln %d unsupported file format: %d", __LINE__, ac->of);
    403         commandFailed(ac);
    404         return;
    405     }
    406 
    407     mOutputFormat = ac->of;
    408 
    409     OSCL_TRY(error, mAuthor->SelectComposer(mComposerMimeType, mComposerConfig, ac));
    410     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    411 }
    412 
    413 void AuthorDriver::media_track_added(status_t status, void *cookie)
    414 {
    415     AuthorDriver *ad = (AuthorDriver *)cookie;
    416 
    417     ad->mSyncSem->Signal();
    418 }
    419 
    420 void AuthorDriver::handleSetAudioEncoder(set_audio_encoder_command *ac)
    421 {
    422     LOGV("AuthorDriver::handleSetAudioEncoder(%d)", ac->ae);
    423 
    424     int error = 0;
    425     OSCL_HeapString<OsclMemAllocator> iAudioEncoderMimeType;
    426 
    427     if (ac->ae == AUDIO_ENCODER_DEFAULT)
    428         ac->ae = AUDIO_ENCODER_AMR_NB;
    429 
    430     switch(ac->ae) {
    431     case AUDIO_ENCODER_AMR_NB:
    432         iAudioEncoderMimeType = "/x-pvmf/audio/encode/amr-nb";
    433         // AMR_NB only supports 8kHz sampling rate
    434         if (mSamplingRate == 0)
    435         {
    436             // Sampling rate not set, use the default
    437             mSamplingRate = 8000;
    438         }
    439         else if (mSamplingRate != 8000)
    440         {
    441             LOGE("Only valid sampling rate for AMR_NB is 8kHz.");
    442             commandFailed(ac);
    443             return;
    444         }
    445 
    446         // AMR_NB only supports mono (IE 1 channel)
    447         if (mNumberOfChannels == 0)
    448         {
    449             // Number of channels not set, use the default
    450             mNumberOfChannels = 1;
    451         }
    452         else if (mNumberOfChannels != 1)
    453         {
    454             LOGE("Only valid number of channels for ANR_NB is 1.");
    455             commandFailed(ac);
    456             return;
    457         }
    458         break;
    459 
    460     case AUDIO_ENCODER_AMR_WB:
    461         iAudioEncoderMimeType = "/x-pvmf/audio/encode/amr-wb";
    462         // AMR_WB only supports 16kHz sampling rate
    463         if (mSamplingRate == 0)
    464         {
    465             // Sampling rate not set, use the default
    466             mSamplingRate = 16000;
    467         }
    468         else if (mSamplingRate != 16000)
    469         {
    470             LOGE("Only valid sampling rate for AMR_WB is 16kHz.");
    471             commandFailed(ac);
    472             return;
    473         }
    474 
    475         // AMR_WB only supports mono (IE 1 channel)
    476         if (mNumberOfChannels == 0)
    477         {
    478             // Number of channels not set, use the default
    479             mNumberOfChannels = 1;
    480         }
    481         else if (mNumberOfChannels != 1)
    482         {
    483             LOGE("Only valid number of channels for ANR_WB is 1.");
    484             commandFailed(ac);
    485             return;
    486         }
    487         break;
    488 
    489     case AUDIO_ENCODER_AAC:
    490         // Check the sampling rate
    491         if (mSamplingRate == 0)
    492         {
    493             // No sampling rate set, use the default
    494             mSamplingRate = DEFAULT_AUDIO_SAMPLING_RATE;
    495         }
    496         // Check the number of channels
    497         if (mNumberOfChannels == 0)
    498         {
    499             // Number of channels not set, use the default
    500             mNumberOfChannels = DEFAULT_AUDIO_NUMBER_OF_CHANNELS;
    501         }
    502 
    503         // Is file container type AAC-ADIF?
    504         if(mOutputFormat == OUTPUT_FORMAT_AAC_ADIF)
    505         {
    506             // This is an audio only file container, set the correct encoder
    507             iAudioEncoderMimeType = "/x-pvmf/audio/encode/aac/adif";
    508         }
    509         // AAC-ADTS?
    510         else if (mOutputFormat == OUTPUT_FORMAT_AAC_ADTS)
    511         {
    512             // This is an audio only file container, set the correct encoder
    513             iAudioEncoderMimeType = "/x-pvmf/audio/encode/aac/adts";
    514         }
    515         // else MPEG4 or 3GPP container ... use AAC-RAW
    516         else
    517         {
    518             // AAC for mixed audio/video containers
    519             iAudioEncoderMimeType = "/x-pvmf/audio/encode/X-MPEG4-AUDIO";
    520         }
    521         break;
    522 
    523     case AUDIO_ENCODER_AAC_PLUS:
    524     case AUDIO_ENCODER_EAAC_PLUS:
    525         // Added for future use.  Not currently supported by pvauthor
    526         LOGE("AAC_PLUS and EAAC_PLUS audio formats are currently not supported");
    527         // NO BREAK!  Fall through from the unsupported AAC_PLUS and EAAC_PLUS cases into default case
    528     default:
    529         commandFailed(ac);
    530         return;
    531     }
    532 
    533     LOGV("AuthorDriver::handleSetAudioEncoder() set %d %d \"%s\"", mSamplingRate, mNumberOfChannels, iAudioEncoderMimeType.get_cstr());
    534 
    535     // Set the sampling rate and number of channels
    536     if (!mAudioInputMIO->setAudioSamplingRate(mSamplingRate))
    537     {
    538         LOGE("Failed to set the sampling rate %d", mSamplingRate);
    539         commandFailed(ac);
    540         return;
    541     }
    542     if (!mAudioInputMIO->setAudioNumChannels(mNumberOfChannels))
    543     {
    544         LOGE("Failed to set the number of channels %d", mNumberOfChannels);
    545         commandFailed(ac);
    546         return;
    547     }
    548 
    549     mAudioEncoder = ac->ae;
    550 
    551     OSCL_TRY(error, mAuthor->AddMediaTrack(*mAudioNode, iAudioEncoderMimeType, mSelectedComposer, mAudioEncoderConfig, ac));
    552     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    553 }
    554 
    555 void AuthorDriver::handleSetVideoEncoder(set_video_encoder_command *ac)
    556 {
    557     int error = 0;
    558     OSCL_HeapString<OsclMemAllocator> iVideoEncoderMimeType;
    559 
    560     if (ac->ve == VIDEO_ENCODER_DEFAULT)
    561         ac->ve = VIDEO_ENCODER_H263;
    562 
    563     switch(ac->ve) {
    564     case VIDEO_ENCODER_H263:
    565         iVideoEncoderMimeType = "/x-pvmf/video/encode/h263";
    566         break;
    567 
    568     case VIDEO_ENCODER_H264:
    569         iVideoEncoderMimeType = "/x-pvmf/video/encode/h264";
    570         break;
    571 
    572     case VIDEO_ENCODER_MPEG_4_SP:
    573         iVideoEncoderMimeType = "/x-pvmf/video/encode/mp4";
    574         break;
    575 
    576     default:
    577         commandFailed(ac);
    578         return;
    579     }
    580 
    581     mVideoEncoder = ac->ve;
    582     // Set video encoding frame rate and video frame size only when the
    583     // video input MIO is set.
    584     if (mVideoInputMIO) {
    585         if (mVideoFrameRate == 0) {
    586             mVideoFrameRate = DEFAULT_VIDEO_FRAME_RATE;
    587         }
    588         clipVideoFrameRate();
    589         ((AndroidCameraInput *)mVideoInputMIO)->SetFrameRate(mVideoFrameRate);
    590 
    591         if (mVideoWidth == 0) {
    592             mVideoWidth = DEFAULT_VIDEO_WIDTH;
    593         }
    594         if (mVideoHeight == 0) {
    595             mVideoHeight = DEFAULT_VIDEO_HEIGHT;
    596         }
    597         clipVideoFrameSize();
    598         ((AndroidCameraInput *)mVideoInputMIO)->SetFrameSize(mVideoWidth, mVideoHeight);
    599     }
    600 
    601     OSCL_TRY(error, mAuthor->AddMediaTrack(*mVideoNode, iVideoEncoderMimeType, mSelectedComposer, mVideoEncoderConfig, ac));
    602     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    603 }
    604 
    605 void AuthorDriver::handleSetVideoSize(set_video_size_command *ac)
    606 {
    607     if (mVideoInputMIO == NULL) {
    608         LOGE("camera MIO is NULL");
    609         commandFailed(ac);
    610         return;
    611     }
    612 
    613     mVideoWidth = ac->width;
    614     mVideoHeight = ac->height;
    615     FinishNonAsyncCommand(ac);
    616 }
    617 
    618 void AuthorDriver::handleSetVideoFrameRate(set_video_frame_rate_command *ac)
    619 {
    620     if (mVideoInputMIO == NULL) {
    621         LOGE("camera MIO is NULL");
    622         commandFailed(ac);
    623         return;
    624     }
    625 
    626     mVideoFrameRate = ac->rate;
    627     FinishNonAsyncCommand(ac);
    628 }
    629 
    630 void AuthorDriver::handleSetCamera(set_camera_command *ac)
    631 {
    632     LOGV("mCamera = %p", ac->camera.get());
    633     mCamera = ac->camera;
    634     FinishNonAsyncCommand(ac);
    635 }
    636 
    637 void AuthorDriver::handleSetPreviewSurface(set_preview_surface_command *ac)
    638 {
    639     if (mVideoInputMIO == NULL) {
    640         LOGE("camera MIO is NULL");
    641         commandFailed(ac);
    642         return;
    643     }
    644 
    645     ((AndroidCameraInput *)mVideoInputMIO)->SetPreviewSurface(ac->surface);
    646     FinishNonAsyncCommand(ac);
    647 }
    648 
    649 void AuthorDriver::handleSetOutputFile(set_output_file_command *ac)
    650 {
    651     PVMFStatus ret = PVMFFailure;
    652     PvmfFileOutputNodeConfigInterface *config = NULL;
    653 
    654     if (!mComposerConfig) goto exit;
    655 
    656     config = OSCL_STATIC_CAST(PvmfFileOutputNodeConfigInterface*, mComposerConfig);
    657     if (!config) goto exit;
    658 
    659     ifpOutput = fdopen(ac->fd, "wb");
    660     if (NULL == ifpOutput) {
    661         LOGE("Ln %d fopen() error", __LINE__);
    662         goto exit;
    663     }
    664 
    665     if (( OUTPUT_FORMAT_AMR_NB == mOutputFormat ) || ( OUTPUT_FORMAT_AMR_WB == mOutputFormat ) ||
    666         ( OUTPUT_FORMAT_AAC_ADIF == mOutputFormat ) || ( OUTPUT_FORMAT_AAC_ADTS == mOutputFormat )) {
    667         PvmfFileOutputNodeConfigInterface *config = OSCL_DYNAMIC_CAST(PvmfFileOutputNodeConfigInterface*, mComposerConfig);
    668         if (!config) goto exit;
    669 
    670         ret = config->SetOutputFileDescriptor(&OsclFileHandle(ifpOutput));
    671     }  else if((OUTPUT_FORMAT_THREE_GPP == mOutputFormat) || (OUTPUT_FORMAT_MPEG_4 == mOutputFormat)){
    672         PVMp4FFCNClipConfigInterface *config = OSCL_DYNAMIC_CAST(PVMp4FFCNClipConfigInterface*, mComposerConfig);
    673         if (!config) goto exit;
    674 
    675         config->SetPresentationTimescale(1000);
    676         ret = config->SetOutputFileDescriptor(&OsclFileHandle(ifpOutput));
    677     }
    678 
    679 
    680 exit:
    681     if (ret == PVMFSuccess) {
    682         FinishNonAsyncCommand(ac);
    683     } else {
    684         LOGE("Ln %d SetOutputFile() error", __LINE__);
    685     if (ifpOutput) {
    686         fclose(ifpOutput);
    687         ifpOutput = NULL;
    688     }
    689         commandFailed(ac);
    690     }
    691 }
    692 
    693 PVMFStatus AuthorDriver::setMaxDurationOrFileSize(
    694         int64_t limit, bool limit_is_duration) {
    695     PVInterface *interface;
    696     PvmfComposerSizeAndDurationInterface *durationConfig;
    697 
    698     if (limit > 0xffffffff) {
    699         // PV API expects this to fit in a uint32.
    700         return PVMFErrArgument;
    701     }
    702 
    703     if (!mComposerConfig) {
    704         return PVMFFailure;
    705     }
    706 
    707     mComposerConfig->queryInterface(
    708             PvmfComposerSizeAndDurationUuid, interface);
    709 
    710     durationConfig =
    711         OSCL_DYNAMIC_CAST(PvmfComposerSizeAndDurationInterface *, interface);
    712 
    713     if (!durationConfig) {
    714         return PVMFFailure;
    715     }
    716 
    717     PVMFStatus ret;
    718     if (limit_is_duration) {
    719         // SetMaxDuration's first parameter is a boolean "enable", we enable
    720         // enforcement of the maximum duration if it's (strictly) positive,
    721         // otherwise we take it to imply disabling.
    722         ret = durationConfig->SetMaxDuration(
    723                 limit > 0, static_cast<uint32>(limit));
    724     } else {
    725         // SetMaxFileSize's first parameter is a boolean "enable", we enable
    726         // enforcement of the maximum filesize if it's (strictly) positive,
    727         // otherwise we take it to imply disabling.
    728         ret = durationConfig->SetMaxFileSize(
    729                 limit > 0, static_cast<uint32>(limit));
    730     }
    731 
    732     durationConfig->removeRef();
    733     durationConfig = NULL;
    734 
    735     return ret;
    736 }
    737 
    738 PVMFStatus AuthorDriver::setParamAudioSamplingRate(int64_t aSamplingRate)
    739 {
    740     // Do a rough check on the incoming sampling rate
    741     if ((aSamplingRate < MIN_AUDIO_SAMPLING_RATE) || (aSamplingRate > MAX_AUDIO_SAMPLING_RATE))
    742     {
    743         LOGE("setParamAudioSamplingRate() invalid sampling rate.");
    744         return PVMFErrArgument;
    745     }
    746 
    747     mSamplingRate = aSamplingRate;
    748     LOGV("setParamAudioSamplingRate() set sampling rate %d", mSamplingRate);
    749     return PVMFSuccess;
    750 }
    751 
    752 
    753 PVMFStatus AuthorDriver::setParamAudioNumberOfChannels(int64_t aNumberOfChannels)
    754 {
    755     // Check the number of channels
    756     if ((aNumberOfChannels < MIN_AUDIO_NUMBER_OF_CHANNELS) || (aNumberOfChannels > MAX_AUDIO_NUMBER_OF_CHANNELS))
    757     {
    758         LOGE("setParamAudioNumberOfChannels() invalid number of channels.");
    759         return PVMFErrArgument;
    760     }
    761 
    762     mNumberOfChannels = aNumberOfChannels;
    763     LOGV("setParamAudioNumberOfChannels() set num channels %d", mNumberOfChannels);
    764     return PVMFSuccess;
    765 }
    766 
    767 PVMFStatus AuthorDriver::setParamAudioEncodingBitrate(int64_t aAudioBitrate)
    768 {
    769     // Map the incoming audio bitrate settings
    770     if ((aAudioBitrate < MIN_AUDIO_BITRATE_SETTING) || (aAudioBitrate > MAX_AUDIO_BITRATE_SETTING))
    771     {
    772         LOGE("setParamAudioEncodingBitrate() invalid audio bitrate.  Set call ignored.");
    773         return PVMFErrArgument;
    774     }
    775 
    776     // Set the audio bitrate
    777     mAudio_bitrate_setting = aAudioBitrate;
    778 
    779     LOGV("setParamAudioEncodingBitrate() %d", mAudio_bitrate_setting);
    780     return PVMFSuccess;
    781 }
    782 
    783 // Attempt to parse an int64 literal optionally surrounded by whitespace,
    784 // returns true on success, false otherwise.
    785 static bool safe_strtoi64(const char *s, int64 *val) {
    786     char *end;
    787     *val = strtoll(s, &end, 10);
    788 
    789     if (end == s || errno == ERANGE) {
    790         return false;
    791     }
    792 
    793     // Skip trailing whitespace
    794     while (isspace(*end)) {
    795         ++end;
    796     }
    797 
    798     // For a successful return, the string must contain nothing but a valid
    799     // int64 literal optionally surrounded by whitespace.
    800 
    801     return *end == '\0';
    802 }
    803 
    804 // Trim both leading and trailing whitespace from the given string.
    805 static void TrimString(String8 *s) {
    806     size_t num_bytes = s->bytes();
    807     const char *data = s->string();
    808 
    809     size_t leading_space = 0;
    810     while (leading_space < num_bytes && isspace(data[leading_space])) {
    811         ++leading_space;
    812     }
    813 
    814     size_t i = num_bytes;
    815     while (i > leading_space && isspace(data[i - 1])) {
    816         --i;
    817     }
    818 
    819     s->setTo(String8(&data[leading_space], i - leading_space));
    820 }
    821 
    822 PVMFStatus AuthorDriver::setParameter(
    823         const String8& key, const String8& value) {
    824     if (key == "max-duration") {
    825         int64_t max_duration_ms;
    826         if (safe_strtoi64(value.string(), &max_duration_ms)) {
    827             return setMaxDurationOrFileSize(
    828                     max_duration_ms, true /* limit_is_duration */);
    829         }
    830     } else if (key == "max-filesize") {
    831         int64_t max_filesize_bytes;
    832         if (safe_strtoi64(value.string(), &max_filesize_bytes)) {
    833             return setMaxDurationOrFileSize(
    834                     max_filesize_bytes, false /* limit is filesize */);
    835         }
    836     } else if (key == "audio-param-sampling-rate") {
    837         int64_t sampling_rate;
    838         if (safe_strtoi64(value.string(), &sampling_rate)) {
    839             return setParamAudioSamplingRate(sampling_rate);
    840         }
    841     } else if (key == "audio-param-number-of-channels") {
    842         int64_t number_of_channels;
    843         if (safe_strtoi64(value.string(), &number_of_channels)) {
    844             return setParamAudioNumberOfChannels(number_of_channels);
    845         }
    846     } else if (key == "audio-param-encoding-bitrate") {
    847         int64_t audio_bitrate;
    848         if (safe_strtoi64(value.string(), &audio_bitrate)) {
    849             return setParamAudioEncodingBitrate(audio_bitrate);
    850         }
    851     } else if (key == "video-param-encoding-bitrate") {
    852         int64_t video_bitrate;
    853         if (safe_strtoi64(value.string(), &video_bitrate)) {
    854             return setParamVideoEncodingBitrate(video_bitrate);
    855         }
    856     }
    857 
    858     // Return error if the key wasnt found
    859     LOGE("AuthorDriver::setParameter() unrecognized key \"%s\"", key.string());
    860     return PVMFErrArgument;
    861 }
    862 
    863 PVMFStatus AuthorDriver::setParamVideoEncodingBitrate(int64_t aVideoBitrate)
    864 {
    865     if (aVideoBitrate <= 0)
    866     {
    867         LOGE("setParamVideoEncodingBitrate() invalid video bitrate (%lld).  Set call ignored.", aVideoBitrate);
    868         return PVMFErrArgument;
    869     }
    870 
    871     mVideo_bitrate_setting = aVideoBitrate;
    872     LOGD("setParamVideoEncodingBitrate() %d", mVideo_bitrate_setting);
    873     return PVMFSuccess;
    874 }
    875 
    876 // Applies the requested parameters, completes either successfully or stops
    877 // application of parameters upon encountering the first error, finishing the
    878 // transaction with the failure result of that initial failure.
    879 void AuthorDriver::handleSetParameters(set_parameters_command *ac) {
    880     PVMFStatus ret = PVMFSuccess;
    881 
    882     const char *params = ac->params().string();
    883     const char *key_start = params;
    884     for (;;) {
    885         const char *equal_pos = strchr(key_start, '=');
    886         if (equal_pos == NULL) {
    887             // This key is missing a value.
    888 
    889             ret = PVMFErrArgument;
    890             break;
    891         }
    892 
    893         String8 key(key_start, equal_pos - key_start);
    894         TrimString(&key);
    895 
    896         if (key.length() == 0) {
    897             ret = PVMFErrArgument;
    898             break;
    899         }
    900 
    901         const char *value_start = equal_pos + 1;
    902         const char *semicolon_pos = strchr(value_start, ';');
    903         String8 value;
    904         if (semicolon_pos == NULL) {
    905             value.setTo(value_start);
    906         } else {
    907             value.setTo(value_start, semicolon_pos - value_start);
    908         }
    909 
    910         ret = setParameter(key, value);
    911 
    912         if (ret != PVMFSuccess) {
    913             LOGE("setParameter(%s = %s) failed with result %d",
    914                  key.string(), value.string(), ret);
    915             break;
    916         }
    917 
    918         if (semicolon_pos == NULL) {
    919             break;
    920         }
    921 
    922         key_start = semicolon_pos + 1;
    923     }
    924 
    925     if (ret == PVMFSuccess) {
    926         FinishNonAsyncCommand(ac);
    927     } else {
    928         LOGE("Ln %d handleSetParameters(\"%s\") error", __LINE__, params);
    929     commandFailed(ac);
    930     }
    931 }
    932 
    933 void AuthorDriver::handlePrepare(author_command *ac)
    934 {
    935     LOGV("handlePrepare");
    936     int error = 0;
    937     OSCL_TRY(error, mAuthor->Init(ac));
    938     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    939 }
    940 
    941 void AuthorDriver::handleStart(author_command *ac)
    942 {
    943     LOGV("handleStart");
    944     int error = 0;
    945     OSCL_TRY(error, mAuthor->Start(ac));
    946     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    947 }
    948 
    949 void AuthorDriver::handleStop(author_command *ac)
    950 {
    951     LOGV("handleStop");
    952     int error = 0;
    953     OSCL_TRY(error, mAuthor->Stop(ac));
    954     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    955 }
    956 
    957 void AuthorDriver::handleClose(author_command *ac)
    958 {
    959     LOGV("handleClose");
    960     int error = 0;
    961     OSCL_TRY(error, mAuthor->Close(ac));
    962     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    963 }
    964 
    965 void AuthorDriver::handleReset(author_command *ac)
    966 {
    967     LOGV("handleReset");
    968     removeConfigRefs(ac);
    969     int error = 0;
    970     OSCL_TRY(error, mAuthor->Reset(ac));
    971     OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    972 }
    973 
    974 void AuthorDriver::handleRemoveVideoSource(author_command *ac)
    975 {
    976     LOGV("handleRemoveVideoSource");
    977     if (mVideoNode) {
    978         int error = 0;
    979         OSCL_TRY(error, mAuthor->RemoveDataSource(*mVideoNode, ac));
    980         OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    981     } else {
    982        FinishNonAsyncCommand(ac);
    983     }
    984 }
    985 
    986 void AuthorDriver::handleRemoveAudioSource(author_command *ac)
    987 {
    988     LOGV("handleRemoveAudioSource");
    989     if (mAudioNode) {
    990         int error = 0;
    991         OSCL_TRY(error, mAuthor->RemoveDataSource(*mAudioNode, ac));
    992         OSCL_FIRST_CATCH_ANY(error, commandFailed(ac));
    993     } else {
    994         FinishNonAsyncCommand(ac);
    995     }
    996 }
    997 
    998 void AuthorDriver::removeConfigRefs(author_command *ac)
    999 {
   1000     LOGV("removeConfigRefs");
   1001 
   1002     if (mComposerConfig) {
   1003         mComposerConfig->removeRef();
   1004         mComposerConfig = NULL;
   1005     }
   1006     if (mVideoEncoderConfig) {
   1007         mVideoEncoderConfig->removeRef();
   1008         mVideoEncoderConfig = NULL;
   1009     }
   1010     if (mAudioEncoderConfig) {
   1011         mAudioEncoderConfig->removeRef();
   1012         mAudioEncoderConfig = NULL;
   1013     }
   1014 }
   1015 
   1016 void AuthorDriver::handleQuit(author_command *ac)
   1017 {
   1018     LOGV("handleQuit");
   1019     OsclExecScheduler *sched = OsclExecScheduler::Current();
   1020     sched->StopScheduler();
   1021 }
   1022 
   1023 /*static*/ int AuthorDriver::startAuthorThread(void *cookie)
   1024 {
   1025     prctl(PR_SET_NAME, (unsigned long) "PV author", 0, 0, 0);
   1026     AuthorDriver *ed = (AuthorDriver *)cookie;
   1027     return ed->authorThread();
   1028 }
   1029 
   1030 void AuthorDriver::doCleanUp()
   1031 {
   1032     if (ifpOutput) {
   1033     fclose(ifpOutput);
   1034     ifpOutput = NULL;
   1035     }
   1036 
   1037     if (mCamera != NULL) {
   1038         mCamera.clear();
   1039     }
   1040 
   1041     if (mVideoNode) {
   1042         PvmfMediaInputNodeFactory::Delete(mVideoNode);
   1043         mVideoNode = NULL;
   1044         delete mVideoInputMIO;
   1045         mVideoInputMIO = NULL;
   1046     }
   1047 
   1048     if (mAudioNode) {
   1049         PvmfMediaInputNodeFactory::Delete(mAudioNode);
   1050         mAudioNode = NULL;
   1051         mAudioInputMIO.clear();
   1052     }
   1053 }
   1054 
   1055 int AuthorDriver::authorThread()
   1056 {
   1057     int error;
   1058 
   1059     LOGV("InitializeForThread");
   1060     if (!InitializeForThread()) {
   1061         LOGE("InitializeForThread failed");
   1062         mAuthor = NULL;
   1063         mSyncSem->Signal();
   1064         return -1;
   1065     }
   1066 
   1067     LOGV("OMX_MasterInit");
   1068     OMX_MasterInit();
   1069 
   1070     OsclScheduler::Init("AndroidAuthorDriver");
   1071     LOGV("Create author ...");
   1072     OSCL_TRY(error, mAuthor = PVAuthorEngineFactory::CreateAuthor(this, this, this));
   1073     if (error) {
   1074         // Just crash the first time someone tries to use it for now?
   1075         LOGE("authorThread init error");
   1076         mAuthor = NULL;
   1077         mSyncSem->Signal();
   1078         return -1;
   1079     }
   1080 
   1081     AddToScheduler();
   1082     PendForExec();
   1083 
   1084     OsclExecScheduler *sched = OsclExecScheduler::Current();
   1085     error = OsclErrNone;
   1086     OSCL_TRY(error, sched->StartScheduler(mSyncSem));
   1087     OSCL_FIRST_CATCH_ANY(error,
   1088              // Some AO did a leave, log it
   1089              LOGE("Author Engine AO did a leave, error=%d", error)
   1090             );
   1091 
   1092     LOGV("Delete Author");
   1093     PVAuthorEngineFactory::DeleteAuthor(mAuthor);
   1094     mAuthor = NULL;
   1095 
   1096 
   1097     // Let the destructor know that we're out
   1098     mSyncStatus = OK;
   1099     mSyncSem->Signal();
   1100     // note that we only signal mSyncSem. Deleting it is handled
   1101     // in enqueueCommand(). This is done because waiting for an
   1102     // already-deleted OsclSemaphore doesn't work (it blocks),
   1103     // and it's entirely possible for this thread to exit before
   1104     // enqueueCommand() gets around to waiting for the semaphore.
   1105 
   1106     // do some of destructor's work here
   1107     // goodbye cruel world
   1108     delete this;
   1109 
   1110    //moved below delete this, similar code on playerdriver.cpp caused a crash.
   1111    //cleanup of oscl should happen at the end.
   1112     OsclScheduler::Cleanup();
   1113     OMX_MasterDeinit();
   1114     UninitializeForThread();
   1115     return 0;
   1116 }
   1117 
   1118 /*static*/ void AuthorDriver::syncCompletion(status_t s, void *cookie)
   1119 {
   1120     AuthorDriver *ed = (AuthorDriver *)cookie;
   1121     ed->mSyncStatus = s;
   1122     ed->mSyncSem->Signal();
   1123 }
   1124 
   1125 // Backward compatible hardcoded video bit rate setting
   1126 // These bit rate settings are from the original work with
   1127 // QCOM's hardware encoders. Originally, anything above
   1128 // 420000 bps is not stable, and default low quality bit
   1129 // rate it set to 192000 bps. For those devices with
   1130 // media capabilities specified as system properties, these
   1131 // bit rate settings will not be used.
   1132 static int setVideoBitrateHeuristically(int videoWidth)
   1133 {
   1134     int bitrate_setting = 192000;
   1135     if (videoWidth >= 480) {
   1136         bitrate_setting = 420000;
   1137     } else if (videoWidth >= 352) {
   1138         bitrate_setting = 360000;
   1139     } else if (videoWidth >= 320) {
   1140         bitrate_setting = 320000;
   1141     }
   1142     return bitrate_setting;
   1143 }
   1144 
   1145 // Clips the intented video encoding rate so that it is
   1146 // within the advertised support range. Logs a warning if
   1147 // the intended bit rate is out of the range.
   1148 void AuthorDriver::clipVideoBitrate()
   1149 {
   1150     int minBitrate = mMediaProfiles->getVideoEncoderParamByName("enc.vid.bps.min", mVideoEncoder);
   1151     int maxBitrate = mMediaProfiles->getVideoEncoderParamByName("enc.vid.bps.max", mVideoEncoder);
   1152     if (mVideo_bitrate_setting < minBitrate) {
   1153         LOGW("Intended video encoding bit rate (%d bps) is too small and will be set to (%lld bps)", mVideo_bitrate_setting, minBitrate);
   1154         mVideo_bitrate_setting = minBitrate;
   1155     } else if (mVideo_bitrate_setting > maxBitrate) {
   1156         LOGW("Intended video encoding bit rate (%d bps) is too large and will be set to (%lld bps)", mVideo_bitrate_setting, maxBitrate);
   1157         mVideo_bitrate_setting = maxBitrate;
   1158     }
   1159 }
   1160 
   1161 void AuthorDriver::clipVideoFrameRate()
   1162 {
   1163     int minFrameRate = mMediaProfiles->getVideoEncoderParamByName("enc.vid.fps.min", mVideoEncoder);
   1164     int maxFrameRate = mMediaProfiles->getVideoEncoderParamByName("enc.vid.fps.max", mVideoEncoder);
   1165     if (mVideoFrameRate < minFrameRate) {
   1166         LOGW("Intended video encoding frame rate (%d fps) is too small and will be set to (%lld fps)", mVideoFrameRate, minFrameRate);
   1167         mVideoFrameRate = minFrameRate;
   1168     } else if (mVideoFrameRate > maxFrameRate) {
   1169         LOGW("Intended video encoding frame rate (%d fps) is too large and will be set to (%lld fps)", mVideoFrameRate, maxFrameRate);
   1170         mVideoFrameRate = maxFrameRate;
   1171     }
   1172 }
   1173 
   1174 void AuthorDriver::clipVideoFrameWidth()
   1175 {
   1176     int minFrameWidth = mMediaProfiles->getVideoEncoderParamByName("enc.vid.width.min", mVideoEncoder);
   1177     int maxFrameWidth = mMediaProfiles->getVideoEncoderParamByName("enc.vid.width.max", mVideoEncoder);
   1178     if (mVideoWidth < minFrameWidth) {
   1179         LOGW("Intended video encoding frame width (%d) is too small and will be set to (%lld)", mVideoWidth, minFrameWidth);
   1180         mVideoWidth = minFrameWidth;
   1181     } else if (mVideoWidth > maxFrameWidth) {
   1182         LOGW("Intended video encoding frame width (%d) is too large and will be set to (%lld)", mVideoWidth, maxFrameWidth);
   1183         mVideoWidth = maxFrameWidth;
   1184     }
   1185 }
   1186 
   1187 void AuthorDriver::clipVideoFrameHeight()
   1188 {
   1189     int minFrameHeight = mMediaProfiles->getVideoEncoderParamByName("enc.vid.height.min", mVideoEncoder);
   1190     int maxFrameHeight = mMediaProfiles->getVideoEncoderParamByName("enc.vid.height.max", mVideoEncoder);
   1191     if (mVideoHeight < minFrameHeight) {
   1192         LOGW("Intended video encoding frame height (%d) is too small and will be set to (%lld)", mVideoHeight, minFrameHeight);
   1193         mVideoHeight = minFrameHeight;
   1194     } else if (mVideoHeight > maxFrameHeight) {
   1195         LOGW("Intended video encoding frame height (%d) is too large and will be set to (%lld)", mVideoHeight, maxFrameHeight);
   1196         mVideoHeight = maxFrameHeight;
   1197     }
   1198 }
   1199 
   1200 void AuthorDriver::clipVideoFrameSize()
   1201 {
   1202     clipVideoFrameWidth();
   1203     clipVideoFrameHeight();
   1204 }
   1205 
   1206 void AuthorDriver::clipAACAudioBitrate()
   1207 {
   1208     /*  ISO-IEC-13818-7 "Information technology.  Generic coding of moving
   1209      *   pictures and associated audio information.  Part 7: Advanced Audio
   1210      *   Coding (AAC)" section 8.2.2.3 defines a formula for the max audio
   1211      *   bitrate based on the audio sampling rate.
   1212      *   6144 (bit/block) / 1024 (samples/block) * sampling_freq * number_of_channels
   1213      *
   1214      *  This method is to calculate the max audio bitrate and clip the desired audio
   1215      *   bitrate if it exceeds its max.
   1216      */
   1217 
   1218     int32 calculated_audio_bitrate = 6 * mSamplingRate * mNumberOfChannels;
   1219     if ((calculated_audio_bitrate > 0) &&
   1220         (mAudio_bitrate_setting > calculated_audio_bitrate))
   1221     {
   1222         // Clip the bitrate setting
   1223         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);
   1224         mAudio_bitrate_setting = calculated_audio_bitrate;
   1225     }
   1226 }
   1227 
   1228 void AuthorDriver::CommandCompleted(const PVCmdResponse& aResponse)
   1229 {
   1230     author_command *ac = (author_command *)aResponse.GetContext();
   1231     status_t s = aResponse.GetCmdStatus();
   1232     LOGV("Command (%d) completed with status(%d)", ac? ac->which: -1, s);
   1233     if (ac == NULL) {
   1234         LOGE("CommandCompleted: Error - null author command!");
   1235         return;
   1236     }
   1237 
   1238     if (ac->which == AUTHOR_SET_OUTPUT_FORMAT) {
   1239         mSelectedComposer = aResponse.GetResponseData();
   1240     }
   1241 
   1242     if (ac->which == AUTHOR_SET_VIDEO_ENCODER) {
   1243         switch(mVideoEncoder) {
   1244         case VIDEO_ENCODER_H263:
   1245         case VIDEO_ENCODER_MPEG_4_SP:
   1246         case VIDEO_ENCODER_H264: {
   1247             PVMp4H263EncExtensionInterface *config = OSCL_STATIC_CAST(PVMp4H263EncExtensionInterface*,
   1248                                                                       mVideoEncoderConfig);
   1249             if (config) {
   1250                 if (mVideo_bitrate_setting == 0) {
   1251                     mVideo_bitrate_setting = setVideoBitrateHeuristically(mVideoWidth);
   1252                     LOGW("Video encoding bit rate is set to %d bps", mVideo_bitrate_setting);
   1253                 }
   1254                 clipVideoBitrate();
   1255                 config->SetNumLayers(1);
   1256                 config->SetOutputBitRate(0, mVideo_bitrate_setting);
   1257                 config->SetOutputFrameSize(0, mVideoWidth, mVideoHeight);
   1258                 config->SetOutputFrameRate(0, mVideoFrameRate);
   1259                 config->SetIFrameInterval(ANDROID_DEFAULT_I_FRAME_INTERVAL);
   1260             }
   1261         } break;
   1262 
   1263         default:
   1264             break;
   1265         }
   1266     }
   1267 
   1268     if (ac->which == AUTHOR_SET_AUDIO_ENCODER) {
   1269         // Perform the cast to get the audio config interface
   1270         PVAudioEncExtensionInterface *config = OSCL_STATIC_CAST(PVAudioEncExtensionInterface*,
   1271                                                                 mAudioEncoderConfig);
   1272 
   1273         if (config)
   1274         {
   1275             switch(mAudioEncoder) {
   1276                 case AUDIO_ENCODER_AMR_NB:
   1277                 case AUDIO_ENCODER_AMR_WB:
   1278                     {
   1279                         // Map the audio bitrate to an AMR discreet bitrate
   1280                         PVMF_GSMAMR_Rate mAMRBitrate;
   1281                         if(!MapAMRBitrate(mAudio_bitrate_setting, mAMRBitrate)) {
   1282                             LOGE("Failed to map the audio bitrate to an AMR bitrate!  Using the defaults.");
   1283                             if (mAudioEncoder == AUDIO_ENCODER_AMR_NB) {
   1284                                 mAMRBitrate = DEFAULT_AMR_NARROW_BAND_BITRATE_SETTING;
   1285                             }
   1286                             else { // Else use the default wideband setting
   1287                                mAMRBitrate = DEFAULT_AMR_WIDE_BAND_BITRATE_SETTING;
   1288                             }
   1289                         }
   1290                         config->SetOutputBitRate(mAMRBitrate);
   1291                         config->SetMaxNumOutputFramesPerBuffer(10);
   1292                     }
   1293                     break;
   1294 
   1295                 case AUDIO_ENCODER_AAC:
   1296                     {
   1297                         if (mAudio_bitrate_setting == 0) {
   1298                             // Audio bitrate wasnt set, use the default
   1299                             mAudio_bitrate_setting = DEFAULT_AUDIO_BITRATE_SETTING;
   1300                         }
   1301                         clipAACAudioBitrate();
   1302                         config->SetOutputBitRate(mAudio_bitrate_setting);
   1303                     }
   1304                     break;
   1305 
   1306                 case AUDIO_ENCODER_AAC_PLUS:
   1307                 case AUDIO_ENCODER_EAAC_PLUS:
   1308                    LOGE("AAC_PLUS and EAAC_PLUS audio formats are currently not supported");
   1309                    // We shouldn't get here.  The setAudioEncoder function should have rejected these.
   1310                    //  These are currently not supported by pvauthor.
   1311                    // NO BREAK!  Fall through from the unsupported AAC_PLUS and EAAC_PLUS cases into default case
   1312                 default:
   1313                     break;
   1314             } // End switch(mAudioEncoder)
   1315         } // End if (config)
   1316     } // End if (ac->which == AUTHOR_SET_AUDIO_ENCODER)
   1317 
   1318     // delete video and/or audio nodes to prevent memory leakage
   1319     // when an authroing session is reused
   1320     if (ac->which == AUTHOR_CLOSE) {
   1321         LOGV("doCleanUp");
   1322         doCleanUp();
   1323     }
   1324 
   1325     // Translate the PVMF error codes into Android ones
   1326     switch(s) {
   1327         case PVMFSuccess: s = android::OK; break;
   1328         case PVMFPending: *(char *)0 = 0; break; /* XXX assert */
   1329         default:
   1330             LOGE("Command %d completed with error %d",ac->which, s);
   1331             // s = android::UNKNOWN_ERROR;
   1332             // FIXME: Similar to mediaplayer, set the return status to
   1333             //        something android specific. For now, use PVMF
   1334             //        return codes as is.
   1335     }
   1336 
   1337     // Call the user's requested completion function
   1338     ac->comp(s, ac->cookie);
   1339 
   1340     delete ac;
   1341 }
   1342 
   1343 bool AuthorDriver::MapAMRBitrate(int32 aAudioBitrate, PVMF_GSMAMR_Rate &anAMRBitrate)
   1344 {
   1345     if ((mAudioEncoder != AUDIO_ENCODER_AMR_NB) &&
   1346             (mAudioEncoder != AUDIO_ENCODER_AMR_WB)) {
   1347         LOGE("AuthorDriver::MapAMRBitrate() encoder type is not AMR.");
   1348         return false;
   1349     }
   1350 
   1351     // Default to AMR_NB
   1352     uint32 AMR_Index = 0;
   1353 
   1354     // Is this ARM_WB?
   1355     if (mAudioEncoder == AUDIO_ENCODER_AMR_WB)
   1356     {
   1357         // Use the other side of the array
   1358         AMR_Index = 1;
   1359     }
   1360 
   1361     uint32 jj;
   1362     for (jj = 0; jj < AMR_BITRATE_MAX_NUMBER_OF_ROWS; jj++)
   1363     {
   1364         if (aAudioBitrate < AMR_BITRATE_MAPPING_ARRAY[jj][AMR_Index].bitrate)
   1365         {
   1366             // Found a match!
   1367             anAMRBitrate = AMR_BITRATE_MAPPING_ARRAY[jj][AMR_Index].actual;
   1368             return true;
   1369         }
   1370     }
   1371 
   1372     // Failed to map the bitrate.  Return false and use the defaults.
   1373     return false;
   1374 }
   1375 
   1376 void AuthorDriver::HandleErrorEvent(const PVAsyncErrorEvent& aEvent)
   1377 {
   1378     LOGE("HandleErrorEvent(%d)", aEvent.GetEventType());
   1379 
   1380     if (mListener != NULL) {
   1381     mListener->notify(
   1382         MEDIA_RECORDER_EVENT_ERROR, MEDIA_RECORDER_ERROR_UNKNOWN,
   1383         aEvent.GetEventType());
   1384     }
   1385 }
   1386 
   1387 static int GetMediaRecorderInfoCode(const PVAsyncInformationalEvent& aEvent) {
   1388     switch (aEvent.GetEventType()) {
   1389         case PVMF_COMPOSER_MAXDURATION_REACHED:
   1390             return MEDIA_RECORDER_INFO_MAX_DURATION_REACHED;
   1391 
   1392         case PVMF_COMPOSER_MAXFILESIZE_REACHED:
   1393             return MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED;
   1394 
   1395         default:
   1396             return MEDIA_RECORDER_INFO_UNKNOWN;
   1397     }
   1398 }
   1399 
   1400 void AuthorDriver::HandleInformationalEvent(const PVAsyncInformationalEvent& aEvent)
   1401 {
   1402     const PVEventType event_type = aEvent.GetEventType();
   1403     assert(!IsPVMFErrCode(event_type));
   1404     if (IsPVMFInfoCode(event_type)) {
   1405         LOGV("HandleInformationalEvent(%d:%s)",
   1406              event_type, PVMFStatusToString(event_type));
   1407     } else {
   1408         LOGV("HandleInformationalEvent(%d)", event_type);
   1409     }
   1410 
   1411     if (PVMFInfoOverflow == event_type && mVideoInputMIO) {
   1412         PVUuid infomsguuid = PVMFDurationInfoMessageInterfaceUUID;
   1413         PVMFDurationInfoMessageInterface* eventMsg = NULL;
   1414         PVInterface* infoExtInterface = aEvent.GetEventExtensionInterface();
   1415         if (infoExtInterface &&
   1416                 infoExtInterface->queryInterface(infomsguuid, (PVInterface*&)eventMsg) && eventMsg) {
   1417             PVUuid eventuuid;
   1418             int32 infoCode;
   1419             eventMsg->GetCodeUUID(infoCode, eventuuid);
   1420             if (eventuuid == infomsguuid) {
   1421                 uint32 duration = eventMsg->GetDuration();
   1422                 ((AndroidCameraInput *)mVideoInputMIO)->setAudioLossDuration(duration);
   1423             }
   1424             eventMsg->removeRef();
   1425             eventMsg = NULL;
   1426         }
   1427     } else {
   1428         mListener->notify(
   1429                 MEDIA_RECORDER_EVENT_INFO,
   1430                 GetMediaRecorderInfoCode(aEvent),
   1431                 aEvent.GetEventType());
   1432     }
   1433 }
   1434 
   1435 status_t AuthorDriver::setListener(const sp<IMediaPlayerClient>& listener) {
   1436     mListener = listener;
   1437 
   1438     return android::OK;
   1439 }
   1440 
   1441 status_t AuthorDriver::getMaxAmplitude(int *max)
   1442 {
   1443     if (mAudioInputMIO == NULL) {
   1444         return android::UNKNOWN_ERROR;
   1445     }
   1446     *max = mAudioInputMIO->maxAmplitude();
   1447     return android::OK;
   1448 }
   1449 
   1450 PVAEState AuthorDriver::getAuthorEngineState()
   1451 {
   1452     if (mAuthor) {
   1453         return mAuthor->GetPVAuthorState();
   1454     }
   1455     return PVAE_STATE_IDLE;
   1456 }
   1457 
   1458