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