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 55 #ifdef HIDE_MIO_SYMBOLS 56 #pragma GCC visibility push(hidden) 57 #endif 58 59 using namespace android; 60 61 class ISurface; 62 class ICamera; 63 64 /** 65 * Enumerated list of asychronous commands for AndroidCameraInput 66 */ 67 typedef enum 68 { 69 CMD_QUERY_UUID, 70 CMD_QUERY_INTERFACE, 71 CMD_INIT, 72 CMD_START, 73 CMD_PAUSE, 74 CMD_FLUSH, 75 CMD_STOP, 76 CMD_CANCEL_ALL_COMMANDS, 77 CMD_CANCEL_COMMAND, 78 CMD_RESET, 79 DATA_EVENT, 80 INVALID_CMD 81 } AndroidCameraInputCmdType; 82 83 #define ANDROID_DEFAULT_FRAME_WIDTH 320 84 #define ANDROID_DEFAULT_FRAME_HEIGHT 240 85 #define ANDROID_DEFAULT_FRAME_RATE 20.0 86 #define ANDROID_DEFAULT_I_FRAME_INTERVAL 1 // encode one I frame every 1 second. 87 #define ANDROID_VIDEO_FORMAT PVMF_MIME_YUV420 88 89 //FIXME mime string now 90 /* 91 #if ANDROID_VIDEO_FORMAT == PVMF_MIME_YUV420 92 #error PV does not support RGB16 93 #endif 94 */ 95 96 /** 97 * Class containing information for a command or data event 98 */ 99 class AndroidCameraInputCmd 100 { 101 public: AndroidCameraInputCmd()102 AndroidCameraInputCmd() 103 { 104 iId = 0; 105 iType = INVALID_CMD; 106 iContext = NULL; 107 iData = NULL; 108 } 109 AndroidCameraInputCmd(const AndroidCameraInputCmd & aCmd)110 AndroidCameraInputCmd(const AndroidCameraInputCmd& aCmd) 111 { 112 Copy(aCmd); 113 } 114 ~AndroidCameraInputCmd()115 ~AndroidCameraInputCmd() {} 116 117 AndroidCameraInputCmd& operator=(const AndroidCameraInputCmd& aCmd) 118 { 119 Copy(aCmd); 120 return (*this); 121 } 122 123 PVMFCommandId iId; /** ID assigned to this command */ 124 int32 iType; /** AndroidCameraInputCmdType value */ 125 OsclAny* iContext; /** Other data associated with this command */ 126 OsclAny* iData; /** Other data associated with this command */ 127 128 private: 129 Copy(const AndroidCameraInputCmd & aCmd)130 void Copy(const AndroidCameraInputCmd& aCmd) 131 { 132 iId = aCmd.iId; 133 iType = aCmd.iType; 134 iContext = aCmd.iContext; 135 iData = aCmd.iData; 136 } 137 }; 138 139 // NOTE: The copy function does a shallow copy, it does not copy the data 140 // pointed to by iFrameBuffer. This is as intended, the memory is safe to use 141 // until camera preview is stopped. 142 class AndroidCameraInputMediaData 143 { 144 public: AndroidCameraInputMediaData()145 AndroidCameraInputMediaData() { 146 memset(this, 0, sizeof(this)); 147 } 148 AndroidCameraInputMediaData(const AndroidCameraInputMediaData & aData)149 AndroidCameraInputMediaData(const AndroidCameraInputMediaData& aData) { 150 Copy(aData); 151 } 152 153 AndroidCameraInputMediaData& operator=(const AndroidCameraInputMediaData& aData) { 154 Copy(aData); 155 return (*this); 156 } 157 158 PVMFCommandId iId; 159 PvmiMediaXferHeader iXferHeader; 160 sp<IMemory> iFrameBuffer; 161 size_t iFrameSize; 162 163 private: Copy(const AndroidCameraInputMediaData & aData)164 void Copy(const AndroidCameraInputMediaData& aData) { 165 iId = aData.iId; 166 iXferHeader = aData.iXferHeader; 167 iFrameBuffer = aData.iFrameBuffer; // won't mess up the reference count 168 iFrameSize = aData.iFrameSize; 169 } 170 }; 171 172 class AndroidCameraInput; 173 class AndroidCameraInputListener : public CameraListener 174 { 175 public: AndroidCameraInputListener(AndroidCameraInput * input)176 AndroidCameraInputListener(AndroidCameraInput* input) { mCameraInput = input; } notify(int32_t msgType,int32_t ext1,int32_t ext2)177 virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) {} 178 virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr); 179 virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); release()180 void release() { mCameraInput = NULL; } 181 private: 182 AndroidCameraInputListener(); 183 AndroidCameraInput* mCameraInput; 184 }; 185 186 class AndroidCameraInput 187 : public OsclTimerObject, 188 public PvmiMIOControl, 189 public PvmiMediaTransfer, 190 public PvmiCapabilityAndConfig 191 { 192 public: 193 AndroidCameraInput(); 194 virtual ~AndroidCameraInput(); 195 196 // Pure virtuals from PvmiMIOControl 197 PVMFStatus connect(PvmiMIOSession& aSession, 198 PvmiMIOObserver* aObserver); 199 200 PVMFStatus disconnect(PvmiMIOSession aSession); 201 PvmiMediaTransfer* createMediaTransfer(PvmiMIOSession& aSession, 202 PvmiKvp* read_formats = NULL, 203 int32 read_flags = 0, 204 PvmiKvp* write_formats = NULL, 205 int32 write_flags = 0); 206 207 void deleteMediaTransfer(PvmiMIOSession& aSession, 208 PvmiMediaTransfer* media_transfer); 209 210 PVMFCommandId QueryUUID(const PvmfMimeString& aMimeType, 211 Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids, 212 bool aExactUuidsOnly = false, 213 const OsclAny* aContext = NULL); 214 215 PVMFCommandId QueryInterface(const PVUuid& aUuid, 216 PVInterface*& aInterfacePtr, 217 const OsclAny* aContext = NULL); 218 219 PVMFCommandId Init(const OsclAny* aContext=NULL); 220 PVMFCommandId Start(const OsclAny* aContext=NULL); 221 PVMFCommandId Reset(const OsclAny* aContext=NULL); 222 PVMFCommandId Pause(const OsclAny* aContext=NULL); 223 PVMFCommandId Flush(const OsclAny* aContext=NULL); 224 PVMFCommandId DiscardData(PVMFTimestamp aTimestamp, 225 const OsclAny* aContext=NULL); 226 227 PVMFCommandId DiscardData(const OsclAny* aContext = NULL); 228 PVMFCommandId Stop(const OsclAny* aContext = NULL); 229 PVMFCommandId CancelCommand(PVMFCommandId aCmdId, 230 const OsclAny* aContext=NULL); 231 232 PVMFCommandId CancelAllCommands(const OsclAny* aContext = NULL); 233 void ThreadLogon(); 234 void ThreadLogoff(); 235 236 // Pure virtuals from PvmiMediaTransfer 237 void setPeer(PvmiMediaTransfer* aPeer); 238 void useMemoryAllocators(OsclMemAllocator* write_alloc = NULL); 239 PVMFCommandId writeAsync(uint8 format_type, 240 int32 format_index, 241 uint8* data, 242 uint32 data_len, 243 const PvmiMediaXferHeader& data_header_info, 244 OsclAny* aContext = NULL); 245 246 void writeComplete(PVMFStatus aStatus, 247 PVMFCommandId write_cmd_id, 248 OsclAny* aContext); 249 250 PVMFCommandId readAsync(uint8* data, 251 uint32 max_data_len, 252 OsclAny* aContext = NULL, 253 int32* formats = NULL, 254 uint16 num_formats = 0); 255 256 void readComplete(PVMFStatus aStatus, 257 PVMFCommandId read_cmd_id, 258 int32 format_index, 259 const PvmiMediaXferHeader& data_header_info, 260 OsclAny* aContext); 261 262 void statusUpdate(uint32 status_flags); 263 void cancelCommand(PVMFCommandId aCmdId); 264 void cancelAllCommands(); 265 266 // Pure virtuals from PvmiCapabilityAndConfig 267 void setObserver (PvmiConfigAndCapabilityCmdObserver* aObserver); 268 PVMFStatus getParametersSync(PvmiMIOSession aSession, 269 PvmiKeyType aIdentifier, 270 PvmiKvp*& aParameters, int& num_parameter_elements, 271 PvmiCapabilityContext aContext); 272 273 PVMFStatus releaseParameters(PvmiMIOSession aSession, 274 PvmiKvp* aParameters, 275 int num_elements); 276 277 void createContext(PvmiMIOSession aSession, 278 PvmiCapabilityContext& aContext); 279 280 void setContextParameters(PvmiMIOSession aSession, 281 PvmiCapabilityContext& aContext, 282 PvmiKvp* aParameters, 283 int num_parameter_elements); 284 285 void DeleteContext(PvmiMIOSession aSession, 286 PvmiCapabilityContext& aContext); 287 288 void setParametersSync(PvmiMIOSession aSession, 289 PvmiKvp* aParameters, 290 int num_elements, 291 PvmiKvp * & aRet_kvp); 292 293 PVMFCommandId setParametersAsync(PvmiMIOSession aSession, 294 PvmiKvp* aParameters, 295 int num_elements, 296 PvmiKvp*& aRet_kvp, 297 OsclAny* context = NULL); 298 299 uint32 getCapabilityMetric (PvmiMIOSession aSession); 300 PVMFStatus verifyParametersSync (PvmiMIOSession aSession, 301 PvmiKvp* aParameters, 302 int num_elements); 303 304 // Android-specific stuff 305 void SetPreviewSurface(const sp<android::ISurface>& surface); 306 void SetFrameSize(int w, int h); 307 void SetFrameRate(int frames_per_second); 308 PVMFStatus SetCamera(const sp<android::ICamera>& camera); 309 310 // add for Camcorder 311 PVMFStatus postWriteAsync(nsecs_t timestamp, const sp<IMemory>& frame); 312 isRecorderStarting()313 bool isRecorderStarting() { return iState==STATE_STARTED?true:false; } 314 315 private: 316 // release all queued recording frames that have not been 317 // given the chance to be sent out. 318 void ReleaseQueuedFrames(); 319 320 void Run(); 321 void FrameSizeChanged(); 322 323 PVMFCommandId AddCmdToQueue(AndroidCameraInputCmdType aType, 324 const OsclAny* aContext, 325 OsclAny* aData1 = NULL); 326 327 void AddDataEventToQueue(uint32 aMicroSecondsToEvent); 328 void DoRequestCompleted(const AndroidCameraInputCmd& aCmd, PVMFStatus aStatus, OsclAny* aEventData=NULL); 329 330 PVMFStatus DoInit(); 331 PVMFStatus DoStart(); 332 PVMFStatus DoReset(); 333 PVMFStatus DoPause(); 334 PVMFStatus DoFlush(const AndroidCameraInputCmd& aCmd); 335 PVMFStatus DoStop(const AndroidCameraInputCmd& aCmd); 336 PVMFStatus DoRead(); 337 338 /** 339 * Allocate a specified number of key-value pairs and set the keys 340 * 341 * @param aKvp Output parameter to hold the allocated key-value pairs 342 * @param aKey Key for the allocated key-value pairs 343 * @param aNumParams Number of key-value pairs to be allocated 344 * @return Completion status 345 */ 346 PVMFStatus AllocateKvp(PvmiKvp*& aKvp, PvmiKeyType aKey, int32 aNumParams); 347 348 /** 349 * Verify one key-value pair parameter against capability of the port and 350 * if the aSetParam flag is set, set the value of the parameter corresponding to 351 * the key. 352 * 353 * @param aKvp Key-value pair parameter to be verified 354 * @param aSetParam If true, set the value of parameter corresponding to the key. 355 * @return PVMFSuccess if parameter is supported, else PVMFFailure 356 */ 357 PVMFStatus VerifyAndSetParameter(PvmiKvp* aKvp, bool aSetParam=false); 358 359 // Command queue 360 uint32 iCmdIdCounter; 361 Oscl_Vector<AndroidCameraInputCmd, OsclMemAllocator> iCmdQueue; 362 363 // PvmiMIO sessions 364 Oscl_Vector<PvmiMIOObserver*, OsclMemAllocator> iObservers; 365 366 PvmiMediaTransfer* iPeer; 367 368 // Thread logon 369 bool iThreadLoggedOn; 370 371 int32 iDataEventCounter; 372 int32 iStartTickCount; 373 374 // Timing 375 int32 iMilliSecondsPerDataEvent; 376 int32 iMicroSecondsPerDataEvent; 377 PVMFTimestamp iTimeStamp; 378 379 // Allocator for simple media data buffer 380 OsclMemAllocator iAlloc; 381 382 Oscl_Vector<AndroidCameraInputMediaData, OsclMemAllocator> iSentMediaData; 383 384 Oscl_Vector<AndroidCameraInputMediaData, OsclMemAllocator> iFrameQueue; 385 OsclMutex iFrameQueueMutex; 386 387 AndroidCameraInputCmd iPendingCmd; 388 389 enum AndroidCameraFlags { 390 FLAGS_SET_CAMERA = 1L << 0, 391 FLAGS_HOT_CAMERA = 1L << 1, 392 }; 393 394 // Camera specific stuff 395 sp<android::ISurface> mSurface; 396 int32 mSurfaceWidth; 397 int32 mSurfaceHeight; 398 int32 mFrameWidth; 399 int32 mFrameHeight; 400 float mFrameRate; 401 sp<android::Camera> mCamera; 402 sp<IMemoryHeap> mHeap; 403 int32 mFrameRefCount; 404 int32 mFlags; 405 406 // callback interface 407 sp<AndroidCameraInputListener> mListener; 408 409 // State machine 410 enum AndroidCameraInputState 411 { 412 STATE_IDLE, 413 STATE_INITIALIZED, 414 STATE_STARTED, 415 STATE_FLUSHING, 416 STATE_PAUSED, 417 STATE_STOPPING, 418 STATE_STOPPED 419 }; 420 421 AndroidCameraInputState iState; 422 423 }; 424 425 #ifdef HIDE_MIO_SYMBOLS 426 #pragma GCC visibility pop 427 #endif 428 429 #endif // ANDROID_CAMERA_INPUT_H_INCLUDED 430