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 #ifndef ANDROID_CAMERA_INPUT_H_INCLUDED
     19 #define ANDROID_CAMERA_INPUT_H_INCLUDED
     20 
     21 #ifndef OSCL_BASE_H_INCLUDED
     22 #include "oscl_base.h"
     23 #endif
     24 #ifndef OSCLCONFIG_IO_H_INCLUDED
     25 #include "osclconfig_io.h"
     26 #endif
     27 #ifndef OSCL_STRING_H_INCLUDED
     28 #include "oscl_string.h"
     29 #endif
     30 #ifndef OSCL_FILE_IO_H_INCLUDED
     31 #include "oscl_file_io.h"
     32 #endif
     33 #ifndef OSCL_MEM_MEMPOOL_H_INCLUDED
     34 #include "oscl_mem_mempool.h"
     35 #endif
     36 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED
     37 #include "oscl_scheduler_ao.h"
     38 #endif
     39 #ifndef OSCL_VECTOR_H_INCLUDED
     40 #include "oscl_vector.h"
     41 #endif
     42 #ifndef PVMI_MIO_CONTROL_H_INCLUDED
     43 #include "pvmi_mio_control.h"
     44 #endif
     45 #ifndef PVMI_MEDIA_TRANSFER_H_INCLUDED
     46 #include "pvmi_media_transfer.h"
     47 #endif
     48 #ifndef PVMI_CONFIG_AND_CAPABILITY_H_INCLUDED
     49 #include "pvmi_config_and_capability.h"
     50 #endif
     51 #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED
     52 #include "pvmf_simple_media_buffer.h"
     53 #endif
     54 #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED
     55 #include "pvmf_media_clock.h"
     56 #endif
     57 
     58 #ifdef HIDE_MIO_SYMBOLS
     59 #pragma GCC visibility push(hidden)
     60 #endif
     61 
     62 using namespace android;
     63 
     64 class ISurface;
     65 class ICamera;
     66 
     67 /**
     68  * Enumerated list of asychronous commands for AndroidCameraInput
     69  */
     70 typedef enum
     71 {
     72     CMD_QUERY_UUID,
     73     CMD_QUERY_INTERFACE,
     74     CMD_INIT,
     75     CMD_START,
     76     CMD_PAUSE,
     77     CMD_FLUSH,
     78     CMD_STOP,
     79     CMD_CANCEL_ALL_COMMANDS,
     80     CMD_CANCEL_COMMAND,
     81     CMD_RESET,
     82     DATA_EVENT,
     83     INVALID_CMD
     84 } AndroidCameraInputCmdType;
     85 
     86 #define ANDROID_DEFAULT_FRAME_WIDTH        320
     87 #define ANDROID_DEFAULT_FRAME_HEIGHT       240
     88 #define ANDROID_DEFAULT_FRAME_RATE         20.0
     89 #define ANDROID_DEFAULT_I_FRAME_INTERVAL 1  // encode one I frame every 1 second.
     90 #ifdef SHOLES_PROPERTY_OVERRIDES
     91 #define ANDROID_VIDEO_FORMAT       PVMF_MIME_YUV422_INTERLEAVED_YUYV
     92 #else
     93 #define ANDROID_VIDEO_FORMAT       PVMF_MIME_YUV420
     94 #endif
     95 
     96 //FIXME mime string now
     97 /*
     98 #if ANDROID_VIDEO_FORMAT == PVMF_MIME_YUV420
     99 #error PV does not support RGB16
    100 #endif
    101 */
    102 
    103 /**
    104  * Class containing information for a command or data event
    105  */
    106 class AndroidCameraInputCmd
    107 {
    108 public:
    109     AndroidCameraInputCmd()
    110     {
    111         iId      = 0;
    112         iType    = INVALID_CMD;
    113         iContext = NULL;
    114         iData    = NULL;
    115     }
    116 
    117     AndroidCameraInputCmd(const AndroidCameraInputCmd& aCmd)
    118     {
    119         Copy(aCmd);
    120     }
    121 
    122     ~AndroidCameraInputCmd() {}
    123 
    124     AndroidCameraInputCmd& operator=(const AndroidCameraInputCmd& aCmd)
    125     {
    126         Copy(aCmd);
    127         return (*this);
    128     }
    129 
    130     PVMFCommandId iId;       /** ID assigned to this command */
    131     int32         iType;     /** AndroidCameraInputCmdType value */
    132     OsclAny*      iContext;  /** Other data associated with this command */
    133     OsclAny*      iData;     /** Other data associated with this command */
    134 
    135 private:
    136 
    137     void Copy(const AndroidCameraInputCmd& aCmd)
    138     {
    139         iId      = aCmd.iId;
    140         iType    = aCmd.iType;
    141         iContext = aCmd.iContext;
    142         iData    = aCmd.iData;
    143     }
    144 };
    145 
    146 // NOTE: The copy function does a shallow copy, it does not copy the data
    147 // pointed to by iFrameBuffer. This is as intended, the memory is safe to use
    148 // until camera preview is stopped.
    149 class AndroidCameraInputMediaData
    150 {
    151 public:
    152     AndroidCameraInputMediaData() {
    153         memset(this, 0, sizeof(this));
    154     }
    155 
    156     AndroidCameraInputMediaData(const AndroidCameraInputMediaData& aData) {
    157        Copy(aData);
    158     }
    159 
    160     AndroidCameraInputMediaData& operator=(const AndroidCameraInputMediaData& aData) {
    161         Copy(aData);
    162         return (*this);
    163     }
    164 
    165     PVMFCommandId           iId;
    166     PvmiMediaXferHeader     iXferHeader;
    167     sp<IMemory>             iFrameBuffer;
    168     size_t                  iFrameSize;
    169 
    170 private:
    171     void Copy(const AndroidCameraInputMediaData& aData) {
    172         iId = aData.iId;
    173         iXferHeader = aData.iXferHeader;
    174         iFrameBuffer = aData.iFrameBuffer;  // won't mess up the reference count
    175         iFrameSize = aData.iFrameSize;
    176     }
    177 };
    178 
    179 class AndroidCameraInput;
    180 class AndroidCameraInputListener : public CameraListener
    181 {
    182 public:
    183     AndroidCameraInputListener(AndroidCameraInput* input) { mCameraInput = input; }
    184     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) {}
    185     virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr);
    186     virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
    187     void release() { mCameraInput = NULL; }
    188 private:
    189     AndroidCameraInputListener();
    190     AndroidCameraInput* mCameraInput;
    191 };
    192 
    193 #ifndef PVMF_FIXEDSIZE_BUFFER_ALLOC_H_INCLUDED
    194 #include "pvmf_fixedsize_buffer_alloc.h"
    195 #endif
    196 
    197 /* A MIO allocater class for two purposes:
    198  * 1. Provide the number of buffers MIO will use;
    199  * 2. Allocate the buffers for OMX_UseBuffer for "buffer pre-announcement". In case MIO cannot
    200  * provide the buffer address, a dummy address is used. The OMX component has to support
    201  * movable buffer(iOMXComponentSupportsMovableInputBuffers) in that case.
    202  */
    203 class PVRefBufferAlloc: public PVInterface, public PVMFFixedSizeBufferAlloc
    204 {
    205     public:
    206         PVRefBufferAlloc()
    207             :refCount(0),
    208             bufferSize(0),
    209             maxBuffers(4), //QCOM camera will use 4 buffers, although it actually only has 3 right now.
    210             numAllocated(0),
    211             pMagicAddr( (OsclAny*)0xDEADBEEF )
    212         {
    213         }
    214 
    215         virtual ~PVRefBufferAlloc();
    216 
    217         virtual void addRef() {++refCount;};
    218 
    219         virtual void removeRef()
    220         {
    221             --refCount;
    222             if (refCount <= 0)
    223             {//cleanup
    224                 LOGW("refCount %d", refCount );
    225             }
    226         }
    227 
    228         virtual bool queryInterface(const PVUuid& uuid, PVInterface*& aInterface)
    229         {
    230             aInterface = NULL; // initialize aInterface to NULL in case uuid is not supported
    231 
    232             if (PVMFFixedSizeBufferAllocUUID == uuid)
    233             {
    234                 // Send back ptr to the allocator interface object
    235                 PVMFFixedSizeBufferAlloc* myInterface   = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, this);
    236                 refCount++; // increment interface refcount before returning ptr
    237                 aInterface = OSCL_STATIC_CAST(PVInterface*, myInterface);
    238                 return true;
    239             }
    240 
    241             return false;
    242         }
    243 
    244         virtual OsclAny* allocate()
    245         {
    246             if (numAllocated < maxBuffers)
    247             {
    248                 //MIO does NOT provide mem allocator impl.
    249                 //return dummy address for OMX buffer pre-announcement.
    250                 ++numAllocated;
    251                 return (OsclAny*)pMagicAddr;
    252             }
    253             return NULL;
    254         }
    255 
    256         virtual void deallocate(OsclAny* ptr)
    257         {
    258             if( pMagicAddr == ptr )
    259             {
    260                 --numAllocated;
    261             }
    262             else
    263             {
    264                 LOGE("Ln %d ERROR PVRefBufferAlloc ptr corrupted 0x%x numAllocated %d", __LINE__, ptr, numAllocated );
    265             }
    266         }
    267 
    268         virtual uint32 getBufferSize()
    269         {
    270             return bufferSize;
    271         }
    272 
    273         virtual uint32 getNumBuffers()
    274         {
    275             return maxBuffers;
    276         }
    277 
    278     private:
    279         int32 refCount;
    280         int32 bufferSize;
    281         int32 maxBuffers;
    282         int32 numAllocated;
    283         const OsclAny *pMagicAddr;
    284 };
    285 
    286 class AndroidCameraInput
    287     : public OsclTimerObject,
    288       public PvmiMIOControl,
    289       public PvmiMediaTransfer,
    290       public PvmiCapabilityAndConfig,
    291       public PVMFMediaClockStateObserver
    292 {
    293 public:
    294     AndroidCameraInput();
    295     virtual ~AndroidCameraInput();
    296 
    297     // Pure virtuals from PvmiMIOControl
    298     PVMFStatus connect(PvmiMIOSession& aSession,
    299         PvmiMIOObserver* aObserver);
    300 
    301     PVMFStatus disconnect(PvmiMIOSession aSession);
    302     PvmiMediaTransfer* createMediaTransfer(PvmiMIOSession& aSession,
    303         PvmiKvp* read_formats = NULL,
    304         int32 read_flags = 0,
    305         PvmiKvp* write_formats = NULL,
    306         int32 write_flags = 0);
    307 
    308     void deleteMediaTransfer(PvmiMIOSession& aSession,
    309                                              PvmiMediaTransfer* media_transfer);
    310 
    311     PVMFCommandId QueryUUID(const PvmfMimeString& aMimeType,
    312         Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
    313         bool aExactUuidsOnly = false,
    314         const OsclAny* aContext = NULL);
    315 
    316     PVMFCommandId QueryInterface(const PVUuid& aUuid,
    317         PVInterface*& aInterfacePtr,
    318         const OsclAny* aContext = NULL);
    319 
    320     PVMFCommandId Init(const OsclAny* aContext=NULL);
    321     PVMFCommandId Start(const OsclAny* aContext=NULL);
    322     PVMFCommandId Reset(const OsclAny* aContext=NULL);
    323     PVMFCommandId Pause(const OsclAny* aContext=NULL);
    324     PVMFCommandId Flush(const OsclAny* aContext=NULL);
    325     PVMFCommandId DiscardData(PVMFTimestamp aTimestamp,
    326         const OsclAny* aContext=NULL);
    327 
    328     PVMFCommandId DiscardData(const OsclAny* aContext = NULL);
    329     PVMFCommandId Stop(const OsclAny* aContext = NULL);
    330     PVMFCommandId CancelCommand(PVMFCommandId aCmdId,
    331         const OsclAny* aContext=NULL);
    332 
    333     PVMFCommandId CancelAllCommands(const OsclAny* aContext = NULL);
    334     void ThreadLogon();
    335     void ThreadLogoff();
    336 
    337     // Pure virtuals from PvmiMediaTransfer
    338     void setPeer(PvmiMediaTransfer* aPeer);
    339     void useMemoryAllocators(OsclMemAllocator* write_alloc = NULL);
    340     PVMFCommandId writeAsync(uint8 format_type,
    341         int32 format_index,
    342         uint8* data,
    343         uint32 data_len,
    344         const PvmiMediaXferHeader& data_header_info,
    345         OsclAny* aContext = NULL);
    346 
    347     void writeComplete(PVMFStatus aStatus,
    348         PVMFCommandId write_cmd_id,
    349         OsclAny* aContext);
    350 
    351     PVMFCommandId readAsync(uint8* data,
    352         uint32 max_data_len,
    353         OsclAny* aContext = NULL,
    354         int32* formats = NULL,
    355         uint16 num_formats = 0);
    356 
    357     void readComplete(PVMFStatus aStatus,
    358         PVMFCommandId read_cmd_id,
    359         int32 format_index,
    360         const PvmiMediaXferHeader& data_header_info,
    361         OsclAny* aContext);
    362 
    363     void statusUpdate(uint32 status_flags);
    364     void cancelCommand(PVMFCommandId aCmdId);
    365     void cancelAllCommands();
    366 
    367     // Pure virtuals from PvmiCapabilityAndConfig
    368     void setObserver (PvmiConfigAndCapabilityCmdObserver* aObserver);
    369     PVMFStatus getParametersSync(PvmiMIOSession aSession,
    370         PvmiKeyType aIdentifier,
    371         PvmiKvp*& aParameters, int& num_parameter_elements,
    372         PvmiCapabilityContext aContext);
    373 
    374     PVMFStatus releaseParameters(PvmiMIOSession aSession,
    375         PvmiKvp* aParameters,
    376         int num_elements);
    377 
    378     void createContext(PvmiMIOSession aSession,
    379         PvmiCapabilityContext& aContext);
    380 
    381     void setContextParameters(PvmiMIOSession aSession,
    382         PvmiCapabilityContext& aContext,
    383         PvmiKvp* aParameters,
    384         int num_parameter_elements);
    385 
    386     void DeleteContext(PvmiMIOSession aSession,
    387         PvmiCapabilityContext& aContext);
    388 
    389     void setParametersSync(PvmiMIOSession aSession,
    390         PvmiKvp* aParameters,
    391         int num_elements,
    392         PvmiKvp * & aRet_kvp);
    393 
    394     PVMFCommandId setParametersAsync(PvmiMIOSession aSession,
    395         PvmiKvp* aParameters,
    396         int num_elements,
    397         PvmiKvp*& aRet_kvp,
    398         OsclAny* context = NULL);
    399 
    400     uint32 getCapabilityMetric (PvmiMIOSession aSession);
    401     PVMFStatus verifyParametersSync (PvmiMIOSession aSession,
    402         PvmiKvp* aParameters,
    403         int num_elements);
    404 
    405     // Android-specific stuff
    406     void SetPreviewSurface(const sp<android::ISurface>& surface);
    407     void SetFrameSize(int w, int h);
    408     void SetFrameRate(int frames_per_second);
    409     PVMFStatus SetCamera(const sp<android::ICamera>& camera);
    410 
    411     // add for Camcorder
    412     PVMFStatus              postWriteAsync(nsecs_t timestamp, const sp<IMemory>& frame);
    413     void setAudioLossDuration(uint32 duration);
    414 
    415     bool isRecorderStarting() { return iState==STATE_STARTED?true:false; }
    416 
    417     /* From PVMFMediaClockStateObserver and its base */
    418     void ClockStateUpdated();
    419     void NotificationsInterfaceDestroyed();
    420 
    421 private:
    422     // release all queued recording frames that have not been
    423     // given the chance to be sent out.
    424     void ReleaseQueuedFrames();
    425 
    426     void Run();
    427     void FrameSizeChanged();
    428 
    429     PVMFCommandId AddCmdToQueue(AndroidCameraInputCmdType aType,
    430         const OsclAny* aContext,
    431         OsclAny* aData1 = NULL);
    432 
    433     void AddDataEventToQueue(uint32 aMicroSecondsToEvent);
    434     void DoRequestCompleted(const AndroidCameraInputCmd& aCmd, PVMFStatus aStatus, OsclAny* aEventData=NULL);
    435 
    436     PVMFStatus DoInit();
    437     PVMFStatus DoStart();
    438     PVMFStatus DoReset();
    439     PVMFStatus DoPause();
    440     PVMFStatus DoFlush(const AndroidCameraInputCmd& aCmd);
    441     PVMFStatus DoStop(const AndroidCameraInputCmd& aCmd);
    442     PVMFStatus DoRead();
    443 
    444     /**
    445      * Allocate a specified number of key-value pairs and set the keys
    446      *
    447      * @param aKvp Output parameter to hold the allocated key-value pairs
    448      * @param aKey Key for the allocated key-value pairs
    449      * @param aNumParams Number of key-value pairs to be allocated
    450      * @return Completion status
    451      */
    452     PVMFStatus AllocateKvp(PvmiKvp*& aKvp, PvmiKeyType aKey, int32 aNumParams);
    453 
    454     /**
    455      * Verify one key-value pair parameter against capability of the port and
    456      * if the aSetParam flag is set, set the value of the parameter corresponding to
    457      * the key.
    458      *
    459      * @param aKvp Key-value pair parameter to be verified
    460      * @param aSetParam If true, set the value of parameter corresponding to the key.
    461      * @return PVMFSuccess if parameter is supported, else PVMFFailure
    462      */
    463     PVMFStatus VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam=false);
    464 
    465     void RemoveDestroyClockObs();
    466 
    467     // Command queue
    468     uint32 iCmdIdCounter;
    469     Oscl_Vector<AndroidCameraInputCmd, OsclMemAllocator> iCmdQueue;
    470 
    471     // PvmiMIO sessions
    472     Oscl_Vector<PvmiMIOObserver*, OsclMemAllocator> iObservers;
    473 
    474     PvmiMediaTransfer* iPeer;
    475 
    476     // Thread logon
    477     bool iThreadLoggedOn;
    478 
    479     int32 iDataEventCounter;
    480 
    481     // Timing
    482     int32 iMilliSecondsPerDataEvent;
    483     int32 iMicroSecondsPerDataEvent;
    484     PVMFTimestamp iTimeStamp;
    485 
    486     // Allocator for simple media data buffer
    487     OsclMemAllocator iAlloc;
    488 
    489     Oscl_Vector<AndroidCameraInputMediaData, OsclMemAllocator> iSentMediaData;
    490 
    491     Oscl_Vector<AndroidCameraInputMediaData, OsclMemAllocator> iFrameQueue;
    492     OsclMutex iFrameQueueMutex;
    493 
    494     AndroidCameraInputCmd iPendingCmd;
    495 
    496     enum AndroidCameraFlags {
    497         FLAGS_SET_CAMERA        = 1L << 0,
    498         FLAGS_HOT_CAMERA        = 1L << 1,
    499     };
    500 
    501     // Camera specific stuff
    502     sp<android::ISurface>   mSurface;
    503     int32                   mSurfaceWidth;
    504     int32                   mSurfaceHeight;
    505     int32                   mFrameWidth;
    506     int32                   mFrameHeight;
    507     float                   mFrameRate;
    508     sp<android::Camera>     mCamera;
    509     int32                   mFlags;
    510 
    511     // callback interface
    512     sp<AndroidCameraInputListener>  mListener;
    513 
    514     // State machine
    515     enum AndroidCameraInputState
    516     {
    517         STATE_IDLE,
    518         STATE_INITIALIZED,
    519         STATE_STARTED,
    520         STATE_FLUSHING,
    521         STATE_PAUSED,
    522         STATE_STOPPING,
    523         STATE_STOPPED
    524     };
    525 
    526     AndroidCameraInputState iState;
    527 
    528     enum WriteState {EWriteBusy, EWriteOK};
    529     WriteState iWriteState;
    530 
    531     PVMFMediaClock *iAuthorClock;
    532     PVMFMediaClockNotificationsInterface *iClockNotificationsInf;
    533 
    534     uint32 iAudioFirstFrameTs;
    535     OsclMutex iAudioLossMutex;
    536     uint32 iAudioLossDuration;
    537     PVRefBufferAlloc    mbufferAlloc;
    538 
    539     // data structures for tunneling buffers
    540     struct CAMERA_PMEM_INFO
    541     {
    542         /* pmem file descriptor */
    543         uint32 pmem_fd;
    544         uint32 offset;
    545     } *pPmemInfo;
    546 
    547 };
    548 
    549 #ifdef HIDE_MIO_SYMBOLS
    550 #pragma GCC visibility pop
    551 #endif
    552 
    553 #endif // ANDROID_CAMERA_INPUT_H_INCLUDED
    554