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 "CameraInput" 20 #include <utils/Log.h> 21 #include <camera/CameraParameters.h> 22 #include <utils/Errors.h> 23 #include <media/mediarecorder.h> 24 #include <surfaceflinger/ISurface.h> 25 #include <camera/ICamera.h> 26 #include <camera/Camera.h> 27 28 #include "pv_mime_string_utils.h" 29 #include "oscl_dll.h" 30 #include "oscl_tickcount.h" 31 32 #include "android_camera_input.h" 33 34 using namespace android; 35 36 static const int VIEW_FINDER_FREEZE_DETECTION_TOLERANCE = 250; // ms 37 38 // Define entry point for this DLL 39 OSCL_DLL_ENTRY_POINT_DEFAULT() 40 41 PVRefBufferAlloc::~PVRefBufferAlloc() 42 { 43 if(numAllocated != 0) 44 { 45 LOGE("Ln %d ERROR PVRefBufferAlloc numAllocated %d",__LINE__, numAllocated ); 46 } 47 } 48 49 // camera MIO 50 AndroidCameraInput::AndroidCameraInput() 51 : OsclTimerObject(OsclActiveObject::EPriorityNominal, "AndroidCameraInput"), 52 iWriteState(EWriteOK), 53 iAuthorClock(NULL), 54 iClockNotificationsInf(NULL), 55 iAudioFirstFrameTs(0), 56 iAudioLossDuration(0), 57 pPmemInfo(NULL) 58 { 59 LOGV("constructor(%p)", this); 60 iCmdIdCounter = 0; 61 iPeer = NULL; 62 iThreadLoggedOn = false; 63 iDataEventCounter = 0; 64 iTimeStamp = 0; 65 iMilliSecondsPerDataEvent = 0; 66 iMicroSecondsPerDataEvent = 0; 67 iState = STATE_IDLE; 68 mFrameWidth = ANDROID_DEFAULT_FRAME_WIDTH; 69 mFrameHeight= ANDROID_DEFAULT_FRAME_HEIGHT; 70 mFrameRate = ANDROID_DEFAULT_FRAME_RATE; 71 mCamera = NULL; 72 73 mFlags = 0; 74 iFrameQueue.reserve(5); 75 iFrameQueueMutex.Create(); 76 iAudioLossMutex.Create(); 77 78 // setup callback listener 79 mListener = new AndroidCameraInputListener(this); 80 } 81 82 void AndroidCameraInput::ReleaseQueuedFrames() 83 { 84 LOGV("ReleaseQueuedFrames"); 85 iFrameQueueMutex.Lock(); 86 while (!iFrameQueue.empty()) { 87 AndroidCameraInputMediaData data = iFrameQueue[0]; 88 iFrameQueue.erase(iFrameQueue.begin()); 89 #if (LOG_NDEBUG == 0) 90 ssize_t offset = 0; 91 size_t size = 0; 92 sp<IMemoryHeap> heap = data.iFrameBuffer->getMemory(&offset, &size); 93 LOGD("writeComplete: ID = %d, base = %p, offset = %ld, size = %d ReleaseQueuedFrames", heap->getHeapID(), heap->base(), offset, size); 94 #endif 95 mCamera->releaseRecordingFrame(data.iFrameBuffer); 96 } 97 if(pPmemInfo) 98 { 99 delete pPmemInfo; 100 pPmemInfo = NULL; 101 } 102 iFrameQueueMutex.Unlock(); 103 } 104 105 AndroidCameraInput::~AndroidCameraInput() 106 { 107 LOGV("destructor"); 108 if (mCamera != NULL) { 109 mCamera->setListener(NULL); 110 ReleaseQueuedFrames(); 111 if ((mFlags & FLAGS_HOT_CAMERA) == 0) { 112 LOGV("camera was cold when we started, stopping preview"); 113 mCamera->stopPreview(); 114 } 115 if (mFlags & FLAGS_SET_CAMERA) { 116 LOGV("unlocking camera to return to app"); 117 mCamera->unlock(); 118 } else { 119 LOGV("disconnect from camera"); 120 mCamera->disconnect(); 121 } 122 mFlags = 0; 123 mCamera.clear(); 124 } 125 iFrameQueueMutex.Close(); 126 iAudioLossMutex.Close(); 127 mListener.clear(); 128 } 129 130 PVMFStatus AndroidCameraInput::connect(PvmiMIOSession& aSession, 131 PvmiMIOObserver* aObserver) 132 { 133 LOGV("connect"); 134 if (!aObserver) { 135 LOGE("observer is a NULL pointer"); 136 return PVMFFailure; 137 } 138 139 int32 err = 0; 140 OSCL_TRY(err, iObservers.push_back(aObserver)); 141 OSCL_FIRST_CATCH_ANY(err, 142 LOGE("Out of memory"); return PVMFErrNoMemory); 143 144 // Session ID is the index of observer in the vector 145 aSession = (PvmiMIOSession)(iObservers.size() - 1); 146 return PVMFSuccess; 147 } 148 149 PVMFStatus AndroidCameraInput::disconnect(PvmiMIOSession aSession) 150 { 151 LOGV("disconnect"); 152 uint32 index = (uint32) aSession; 153 uint32 size = iObservers.size(); 154 if (index >= size) { 155 LOGE("Invalid session ID %d. Valid range is [0, %d]", index, size - 1); 156 return PVMFFailure; 157 } 158 159 iObservers.erase(iObservers.begin() + index); 160 return PVMFSuccess; 161 } 162 163 PvmiMediaTransfer* AndroidCameraInput::createMediaTransfer( 164 PvmiMIOSession& aSession, 165 PvmiKvp* read_formats, 166 int32 read_flags, 167 PvmiKvp* write_formats, 168 int32 write_flags) 169 { 170 LOGV("createMediaTransfer"); 171 OSCL_UNUSED_ARG(read_formats); 172 OSCL_UNUSED_ARG(read_flags); 173 OSCL_UNUSED_ARG(write_formats); 174 OSCL_UNUSED_ARG(write_flags); 175 176 uint32 index = (uint32) aSession; 177 uint32 size = iObservers.size(); 178 if (index >= size) { 179 LOGE("Invalid session ID %d. Valid range is [0, %d]", index, size - 1); 180 OSCL_LEAVE(OsclErrArgument); 181 return NULL; 182 } 183 184 return (PvmiMediaTransfer*)this; 185 } 186 187 void AndroidCameraInput::deleteMediaTransfer(PvmiMIOSession& aSession, 188 PvmiMediaTransfer* media_transfer) 189 { 190 LOGV("deleteMediaTransfer"); 191 uint32 index = (uint32) aSession; 192 uint32 size = iObservers.size(); 193 if (index >= size) { 194 LOGE("Invalid session ID %d. Valid range is [0, %d]", index, size - 1); 195 OSCL_LEAVE(OsclErrArgument); 196 return; 197 } 198 if (!media_transfer) { 199 LOGE("media transfer is a NULL pointer"); 200 OSCL_LEAVE(OsclErrArgument); 201 } 202 203 // TODO: 204 // 1. I did not see how the media transfer session has been terminated 205 // after this method call. 206 // 2. according to pvmi_mio_control.h, this should also check with there 207 // is any outstanding buffer? 208 } 209 210 PVMFCommandId AndroidCameraInput::QueryUUID(const PvmfMimeString& aMimeType, 211 Oscl_Vector<PVUuid, 212 OsclMemAllocator>& aUuids, 213 bool aExactUuidsOnly, 214 const OsclAny* aContext) 215 { 216 LOGV("QueryUUID"); 217 OSCL_UNUSED_ARG(aMimeType); 218 OSCL_UNUSED_ARG(aExactUuidsOnly); 219 220 int32 err = 0; 221 OSCL_TRY(err, aUuids.push_back(PVMI_CAPABILITY_AND_CONFIG_PVUUID);); 222 OSCL_FIRST_CATCH_ANY(err, 223 LOGE("Out of memory"); OSCL_LEAVE(OsclErrNoMemory)); 224 225 return AddCmdToQueue(CMD_QUERY_UUID, aContext); 226 } 227 228 PVMFCommandId AndroidCameraInput::QueryInterface(const PVUuid& aUuid, 229 PVInterface*& aInterfacePtr, 230 const OsclAny* aContext) 231 { 232 LOGV("QueryInterface"); 233 if (aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID) { 234 PvmiCapabilityAndConfig* 235 myInterface = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*,this); 236 237 aInterfacePtr = OSCL_STATIC_CAST(PVInterface*, myInterface); 238 } else { 239 aInterfacePtr = NULL; 240 } 241 242 return AddCmdToQueue(CMD_QUERY_INTERFACE, 243 aContext, 244 (OsclAny*)&aInterfacePtr); 245 } 246 247 PVMFCommandId AndroidCameraInput::Init(const OsclAny* aContext) 248 { 249 LOGV("Init"); 250 if (iState != STATE_IDLE) { 251 LOGE("Init called in an invalid state(%d)", iState); 252 OSCL_LEAVE(OsclErrInvalidState); 253 return -1; 254 } 255 256 return AddCmdToQueue(CMD_INIT, aContext); 257 } 258 259 260 PVMFCommandId AndroidCameraInput::Start(const OsclAny* aContext) 261 { 262 LOGV("Start"); 263 if (iState != STATE_INITIALIZED && iState != STATE_PAUSED) { 264 LOGE("Start called in an invalid state(%d)", iState); 265 OSCL_LEAVE(OsclErrInvalidState); 266 return -1; 267 } 268 269 return AddCmdToQueue(CMD_START, aContext); 270 } 271 272 PVMFCommandId AndroidCameraInput::Pause(const OsclAny* aContext) 273 { 274 LOGV("Pause"); 275 if (iState != STATE_STARTED) { 276 LOGE("Pause called in an invalid state(%d)", iState); 277 OSCL_LEAVE(OsclErrInvalidState); 278 return -1; 279 } 280 281 return AddCmdToQueue(CMD_PAUSE, aContext); 282 } 283 284 PVMFCommandId AndroidCameraInput::Flush(const OsclAny* aContext) 285 { 286 LOGV("Flush"); 287 if (iState != STATE_STARTED && iState != STATE_PAUSED) { 288 LOGE("Flush called in an invalid state(%d)", iState); 289 OSCL_LEAVE(OsclErrInvalidState); 290 return -1; 291 } 292 293 return AddCmdToQueue(CMD_FLUSH, aContext); 294 } 295 296 PVMFCommandId AndroidCameraInput::Reset(const OsclAny* aContext) 297 { 298 LOGV("Reset"); 299 return AddCmdToQueue(CMD_RESET, aContext); 300 } 301 302 PVMFCommandId AndroidCameraInput::DiscardData(PVMFTimestamp aTimestamp, 303 const OsclAny* aContext) 304 { 305 LOGV("DiscardData with time stamp"); 306 OSCL_UNUSED_ARG(aContext); 307 OSCL_UNUSED_ARG(aTimestamp); 308 OSCL_LEAVE(OsclErrNotSupported); 309 return -1; 310 } 311 312 PVMFCommandId AndroidCameraInput::DiscardData(const OsclAny* aContext) 313 { 314 LOGV("DiscardData"); 315 OSCL_UNUSED_ARG(aContext); 316 OSCL_LEAVE(OsclErrNotSupported); 317 return -1; 318 } 319 320 PVMFCommandId AndroidCameraInput::Stop(const OsclAny* aContext) 321 { 322 LOGV("Stop"); 323 if (iState != STATE_STARTED && iState != STATE_PAUSED) { 324 LOGE("Stop called in an invalid state(%d)", iState); 325 OSCL_LEAVE(OsclErrInvalidState); 326 return -1; 327 } 328 329 return AddCmdToQueue(CMD_STOP, aContext); 330 } 331 332 void AndroidCameraInput::ThreadLogon() 333 { 334 LOGV("ThreadLogon"); 335 if (!iThreadLoggedOn) { 336 AddToScheduler(); 337 iThreadLoggedOn = true; 338 } 339 } 340 341 void AndroidCameraInput::ThreadLogoff() 342 { 343 LOGV("ThreadLogoff"); 344 if (iThreadLoggedOn) { 345 RemoveFromScheduler(); 346 iThreadLoggedOn = false; 347 } 348 } 349 350 PVMFCommandId AndroidCameraInput::CancelAllCommands(const OsclAny* aContext) 351 { 352 LOGV("CancelAllCommands"); 353 OSCL_UNUSED_ARG(aContext); 354 OSCL_LEAVE(OsclErrNotSupported); 355 return -1; 356 } 357 358 PVMFCommandId AndroidCameraInput::CancelCommand(PVMFCommandId aCmdId, 359 const OsclAny* aContext) 360 { 361 LOGV("CancelCommand"); 362 OSCL_UNUSED_ARG(aCmdId); 363 OSCL_UNUSED_ARG(aContext); 364 OSCL_LEAVE(OsclErrNotSupported); 365 return -1; 366 } 367 368 void AndroidCameraInput::setPeer(PvmiMediaTransfer* aPeer) 369 { 370 LOGV("setPeer iPeer %p aPeer %p", iPeer, aPeer); 371 if(iPeer && aPeer){ 372 LOGE("setPeer iPeer %p aPeer %p", iPeer, aPeer); 373 OSCL_LEAVE(OsclErrGeneral); 374 return; 375 } 376 377 iPeer = aPeer; 378 } 379 380 void AndroidCameraInput::useMemoryAllocators(OsclMemAllocator* write_alloc) 381 { 382 LOGV("useMemoryAllocators"); 383 OSCL_UNUSED_ARG(write_alloc); 384 OSCL_LEAVE(OsclErrNotSupported); 385 } 386 387 PVMFCommandId AndroidCameraInput::writeAsync(uint8 aFormatType, 388 int32 aFormatIndex, 389 uint8* aData, 390 uint32 aDataLen, 391 const PvmiMediaXferHeader& data_header_info, 392 OsclAny* aContext) 393 { 394 LOGV("writeAsync"); 395 OSCL_UNUSED_ARG(aFormatType); 396 OSCL_UNUSED_ARG(aFormatIndex); 397 OSCL_UNUSED_ARG(aData); 398 OSCL_UNUSED_ARG(aDataLen); 399 OSCL_UNUSED_ARG(data_header_info); 400 OSCL_UNUSED_ARG(aContext); 401 // This is an active data source. writeAsync is not supported. 402 OSCL_LEAVE(OsclErrNotSupported); 403 return -1; 404 } 405 406 void AndroidCameraInput::writeComplete(PVMFStatus aStatus, 407 PVMFCommandId write_cmd_id, 408 OsclAny* aContext) 409 { 410 LOGV("writeComplete"); 411 OSCL_UNUSED_ARG(aContext); 412 413 iFrameQueueMutex.Lock(); 414 if (iSentMediaData.empty()) { 415 LOGE("Nothing to complete"); 416 iFrameQueueMutex.Unlock(); 417 return; 418 } 419 420 AndroidCameraInputMediaData data = iSentMediaData[0]; 421 #if (LOG_NDEBUG == 0) 422 ssize_t offset = 0; 423 size_t size = 0; 424 sp<IMemoryHeap> heap = data.iFrameBuffer->getMemory(&offset, &size); 425 LOGD("writeComplete: ID = %d, base = %p, offset = %ld, size = %d", heap->getHeapID(), heap->base(), offset, size); 426 #endif 427 // View finder freeze detection 428 // Note for low frame rate, we don't bother to log view finder freezes 429 int processingTimeInMs = (systemTime()/1000000L - (iAudioFirstFrameTs + iAudioLossDuration)) - data.iXferHeader.timestamp; 430 if (processingTimeInMs >= VIEW_FINDER_FREEZE_DETECTION_TOLERANCE && mFrameRate >= 10.0) { 431 LOGW("Frame %p takes too long (%d ms) to process, staring at %d", data.iFrameBuffer.get(), processingTimeInMs, iAudioFirstFrameTs); 432 } 433 mCamera->releaseRecordingFrame(data.iFrameBuffer); 434 435 iSentMediaData.erase(iSentMediaData.begin()); 436 iFrameQueueMutex.Unlock(); 437 438 // reference count is always updated, even if the write fails 439 if (aStatus != PVMFSuccess) { 440 LOGE("writeAsync failed. aStatus=%d", aStatus); 441 } 442 } 443 444 PVMFCommandId AndroidCameraInput::readAsync(uint8* data, 445 uint32 max_data_len, 446 OsclAny* aContext, 447 int32* formats, 448 uint16 num_formats) 449 { 450 LOGV("readAsync"); 451 OSCL_UNUSED_ARG(data); 452 OSCL_UNUSED_ARG(max_data_len); 453 OSCL_UNUSED_ARG(aContext); 454 OSCL_UNUSED_ARG(formats); 455 OSCL_UNUSED_ARG(num_formats); 456 // This is an active data source. readAsync is not supported. 457 OSCL_LEAVE(OsclErrNotSupported); 458 return -1; 459 } 460 461 void AndroidCameraInput::readComplete(PVMFStatus aStatus, 462 PVMFCommandId read_cmd_id, 463 int32 format_index, 464 const PvmiMediaXferHeader& data_header_info, 465 OsclAny* aContext) 466 { 467 LOGV("readComplete"); 468 OSCL_UNUSED_ARG(aStatus); 469 OSCL_UNUSED_ARG(read_cmd_id); 470 OSCL_UNUSED_ARG(format_index); 471 OSCL_UNUSED_ARG(data_header_info); 472 OSCL_UNUSED_ARG(aContext); 473 // This is an active data source. readComplete is not supported. 474 OSCL_LEAVE(OsclErrNotSupported); 475 return; 476 } 477 478 void AndroidCameraInput::statusUpdate(uint32 status_flags) 479 { 480 LOGV("statusUpdate"); 481 if (status_flags != PVMI_MEDIAXFER_STATUS_WRITE) 482 { 483 OSCL_LEAVE(OsclErrNotSupported); 484 } 485 else 486 { 487 // Restart the flow of data 488 iWriteState = EWriteOK; 489 } 490 } 491 492 void AndroidCameraInput::cancelCommand(PVMFCommandId aCmdId) 493 { 494 LOGV("cancelCommand"); 495 OSCL_UNUSED_ARG(aCmdId); 496 497 // This cancel command ( with a small "c" in cancel ) is for the media 498 // transfer interface. implementation is similar to the cancel command 499 // of the media I/O interface. 500 OSCL_LEAVE(OsclErrNotSupported); 501 } 502 503 void AndroidCameraInput::cancelAllCommands() 504 { 505 LOGV("cancelAllCommands"); 506 OSCL_LEAVE(OsclErrNotSupported); 507 } 508 509 void AndroidCameraInput::setObserver( 510 PvmiConfigAndCapabilityCmdObserver* aObserver) 511 { 512 LOGV("setObserver"); 513 OSCL_UNUSED_ARG(aObserver); 514 } 515 516 PVMFStatus AndroidCameraInput::getParametersSync(PvmiMIOSession session, 517 PvmiKeyType identifier, 518 PvmiKvp*& params, 519 int& num_params, 520 PvmiCapabilityContext context) 521 { 522 LOGV("getParametersSync"); 523 OSCL_UNUSED_ARG(session); 524 OSCL_UNUSED_ARG(context); 525 526 params = NULL; 527 num_params = 0; 528 PVMFStatus status = PVMFFailure; 529 530 if (!pv_mime_strcmp(identifier, OUTPUT_FORMATS_CAP_QUERY) || 531 !pv_mime_strcmp(identifier, OUTPUT_FORMATS_CUR_QUERY)) { 532 num_params = 1; 533 status = AllocateKvp(params, (PvmiKeyType)OUTPUT_FORMATS_VALTYPE, num_params); 534 if (status != PVMFSuccess) { 535 LOGE("AllocateKvp failed for OUTPUT_FORMATS_VALTYP"); 536 return status; 537 } 538 params[0].value.pChar_value = (char*)ANDROID_VIDEO_FORMAT; 539 } else if (!pv_mime_strcmp(identifier, VIDEO_OUTPUT_WIDTH_CUR_QUERY)) { 540 num_params = 1; 541 status = AllocateKvp(params, (PvmiKeyType)VIDEO_OUTPUT_WIDTH_CUR_VALUE, num_params); 542 if (status != PVMFSuccess) { 543 LOGE("AllocateKvp failed for VIDEO_OUTPUT_WIDTH_CUR_VALUE"); 544 return status; 545 } 546 params[0].value.uint32_value = mFrameWidth; 547 } else if (!pv_mime_strcmp(identifier, VIDEO_OUTPUT_HEIGHT_CUR_QUERY)) { 548 num_params = 1; 549 status = AllocateKvp(params, (PvmiKeyType)VIDEO_OUTPUT_HEIGHT_CUR_VALUE, num_params); 550 if (status != PVMFSuccess) { 551 LOGE("AllocateKvp failed for VIDEO_OUTPUT_HEIGHT_CUR_VALUE"); 552 return status; 553 } 554 params[0].value.uint32_value = mFrameHeight; 555 } else if (!pv_mime_strcmp(identifier, VIDEO_OUTPUT_FRAME_RATE_CUR_QUERY)) { 556 num_params = 1; 557 status = AllocateKvp(params, 558 (PvmiKeyType)VIDEO_OUTPUT_FRAME_RATE_CUR_VALUE, num_params); 559 if (status != PVMFSuccess) { 560 LOGE("AllocateKvp failed for VIDEO_OUTPUT_FRAME_RATE_CUR_VALUE"); 561 return status; 562 } 563 params[0].value.float_value = mFrameRate; 564 } else if (!pv_mime_strcmp(identifier, OUTPUT_TIMESCALE_CUR_QUERY)) { 565 num_params = 1; 566 status = AllocateKvp(params, (PvmiKeyType)OUTPUT_TIMESCALE_CUR_VALUE, num_params); 567 if (status != PVMFSuccess) { 568 LOGE("AllocateKvp failed for OUTPUT_TIMESCALE_CUR_VALUE"); 569 return status; 570 } 571 // TODO: 572 // is it okay to hardcode this as the timescale? 573 params[0].value.uint32_value = 1000; 574 } else if (!pv_mime_strcmp(identifier, PVMF_BUFFER_ALLOCATOR_KEY)) { 575 /* 576 * if( camera MIO does NOT allocate YUV buffers ) 577 * { 578 * OSCL_LEAVE(OsclErrNotSupported); 579 * return PVMFErrNotSupported; 580 * } 581 */ 582 583 params = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp)); 584 if (!params ) 585 { 586 OSCL_LEAVE(OsclErrNoMemory); 587 return PVMFErrNoMemory; 588 } 589 params [0].value.key_specific_value = (PVInterface*)&mbufferAlloc; 590 status = PVMFSuccess; 591 } 592 593 return status; 594 } 595 596 PVMFStatus AndroidCameraInput::releaseParameters(PvmiMIOSession session, 597 PvmiKvp* parameters, 598 int num_elements) 599 { 600 LOGV("releaseParameters"); 601 OSCL_UNUSED_ARG(session); 602 OSCL_UNUSED_ARG(num_elements); 603 604 if (!parameters) { 605 LOGE("parameters is a NULL pointer"); 606 return PVMFFailure; 607 } 608 iAlloc.deallocate((OsclAny*)parameters); 609 return PVMFSuccess; 610 } 611 612 void AndroidCameraInput::createContext(PvmiMIOSession session, 613 PvmiCapabilityContext& context) 614 { 615 LOGV("createContext"); 616 OSCL_UNUSED_ARG(session); 617 OSCL_UNUSED_ARG(context); 618 } 619 620 void AndroidCameraInput::setContextParameters(PvmiMIOSession session, 621 PvmiCapabilityContext& context, 622 PvmiKvp* parameters, 623 int num_parameter_elements) 624 { 625 LOGV("setContextParameters"); 626 OSCL_UNUSED_ARG(session); 627 OSCL_UNUSED_ARG(context); 628 OSCL_UNUSED_ARG(parameters); 629 OSCL_UNUSED_ARG(num_parameter_elements); 630 } 631 632 void AndroidCameraInput::DeleteContext(PvmiMIOSession session, 633 PvmiCapabilityContext& context) 634 { 635 LOGV("DeleteContext"); 636 OSCL_UNUSED_ARG(session); 637 OSCL_UNUSED_ARG(context); 638 } 639 640 void AndroidCameraInput::setParametersSync(PvmiMIOSession session, 641 PvmiKvp* parameters, 642 int num_elements, 643 PvmiKvp*& ret_kvp) 644 { 645 LOGV("setParametersSync"); 646 OSCL_UNUSED_ARG(session); 647 PVMFStatus status = PVMFSuccess; 648 ret_kvp = NULL; 649 for (int32 i = 0; i < num_elements; ++i) { 650 status = VerifyAndSetParameter(&(parameters[i]), true); 651 if (status != PVMFSuccess) { 652 LOGE("VerifiyAndSetParameter failed on parameter #%d", i); 653 ret_kvp = &(parameters[i]); 654 OSCL_LEAVE(OsclErrArgument); 655 return; 656 } 657 } 658 } 659 660 PVMFCommandId AndroidCameraInput::setParametersAsync(PvmiMIOSession session, 661 PvmiKvp* parameters, 662 int num_elements, 663 PvmiKvp*& ret_kvp, 664 OsclAny* context) 665 { 666 LOGV("setParametersAsync"); 667 OSCL_UNUSED_ARG(session); 668 OSCL_UNUSED_ARG(parameters); 669 OSCL_UNUSED_ARG(num_elements); 670 OSCL_UNUSED_ARG(ret_kvp); 671 OSCL_UNUSED_ARG(context); 672 OSCL_LEAVE(OsclErrNotSupported); 673 return -1; 674 } 675 676 uint32 AndroidCameraInput::getCapabilityMetric (PvmiMIOSession session) 677 { 678 LOGV("getCapabilityMetric"); 679 OSCL_UNUSED_ARG(session); 680 return 0; 681 } 682 683 PVMFStatus AndroidCameraInput::verifyParametersSync(PvmiMIOSession session, 684 PvmiKvp* parameters, 685 int num_elements) 686 { 687 LOGV("verifyParametersSync"); 688 OSCL_UNUSED_ARG(session); 689 OSCL_UNUSED_ARG(parameters); 690 OSCL_UNUSED_ARG(num_elements); 691 return PVMFErrNotSupported; 692 } 693 694 695 void AndroidCameraInput::SetFrameSize(int w, int h) 696 { 697 LOGV("SetFrameSize"); 698 if (iState != STATE_IDLE) { 699 LOGE("SetFrameSize called in an invalid state(%d)", iState); 700 return; 701 } 702 703 mFrameWidth = w; 704 mFrameHeight = h; 705 FrameSizeChanged(); 706 } 707 708 void AndroidCameraInput::SetFrameRate(int fps) 709 { 710 LOGV("SetFrameRate"); 711 if (iState != STATE_IDLE) { 712 LOGE("SetFrameRate called in an invalid state(%d)", iState); 713 return; 714 } 715 716 mFrameRate = (float)fps; 717 } 718 719 void AndroidCameraInput::FrameSizeChanged() 720 { 721 LOGV("FrameSizeChanged"); 722 if (iState != STATE_IDLE) { 723 LOGE("FrameSizeChanged called in an invalid state(%d)", iState); 724 return; 725 } 726 727 // Reinitialize the preview surface in case it was set up before now 728 if (mSurface != NULL) { 729 SetPreviewSurface(mSurface); 730 } 731 } 732 733 void AndroidCameraInput::Run() 734 { 735 LOGV("Run"); 736 737 // dequeue frame buffers and write to peer 738 if (NULL != iPeer) { 739 if (iState != STATE_STARTED) { 740 ReleaseQueuedFrames(); 741 } 742 iFrameQueueMutex.Lock(); 743 while (!iFrameQueue.empty()) { 744 AndroidCameraInputMediaData data = iFrameQueue[0]; 745 746 uint32 writeAsyncID = 0; 747 OsclLeaveCode error = OsclErrNone; 748 uint8 *ptr = (uint8*) (data.iFrameBuffer->pointer()); 749 if (ptr) { 750 OSCL_TRY(error,writeAsyncID = iPeer->writeAsync(PVMI_MEDIAXFER_FMT_TYPE_DATA, 0, ptr, 751 data.iFrameSize, data.iXferHeader);); 752 } else { 753 //FIXME Check why camera sends NULL frames 754 LOGE("Ln %d ERROR null pointer", __LINE__); 755 error = OsclErrBadHandle; 756 } 757 758 if (OsclErrNone == error) { 759 iFrameQueue.erase(iFrameQueue.begin()); 760 data.iId = writeAsyncID; 761 iSentMediaData.push_back(data); 762 LOGV("Ln %d Run writeAsync writeAsyncID %d", __LINE__, writeAsyncID); 763 } else { 764 //FIXME resend the frame later if ( OsclErrBusy == error) 765 LOGE("Ln %d Run writeAsync error %d", __LINE__, error); 766 //release buffer immediately if write fails 767 mCamera->releaseRecordingFrame(data.iFrameBuffer); 768 iFrameQueue.erase(iFrameQueue.begin()); 769 iWriteState = EWriteBusy; 770 break; 771 } 772 } 773 iFrameQueueMutex.Unlock(); 774 } 775 776 PVMFStatus status = PVMFFailure; 777 778 if (!iCmdQueue.empty()) { 779 AndroidCameraInputCmd cmd = iCmdQueue[0]; 780 iCmdQueue.erase(iCmdQueue.begin()); 781 782 switch(cmd.iType) { 783 784 case CMD_INIT: 785 status = DoInit(); 786 break; 787 788 case CMD_START: 789 status = DoStart(); 790 break; 791 792 case CMD_PAUSE: 793 status = DoPause(); 794 break; 795 796 case CMD_FLUSH: 797 status = DoFlush(cmd); 798 break; 799 800 case CMD_RESET: 801 status = DoReset(); 802 break; 803 804 case CMD_STOP: 805 status = DoStop(cmd); 806 break; 807 808 case DATA_EVENT: 809 // this is internal only - don't send RequestCompleted 810 DoRead(); 811 status = PVMFPending; 812 break; 813 814 case CMD_QUERY_UUID: 815 case CMD_QUERY_INTERFACE: 816 status = PVMFSuccess; 817 break; 818 819 // these commands all fail 820 case CMD_CANCEL_ALL_COMMANDS: 821 case CMD_CANCEL_COMMAND: 822 default: 823 break; 824 } 825 // do RequestCompleted unless command is still pending 826 if (status != PVMFPending) { 827 DoRequestCompleted(cmd, status); 828 } 829 } 830 831 if (!iCmdQueue.empty()) { 832 // Run again if there are more things to process 833 RunIfNotReady(); 834 } 835 } 836 837 PVMFCommandId AndroidCameraInput::AddCmdToQueue(AndroidCameraInputCmdType aType, 838 const OsclAny* aContext, 839 OsclAny* aData) 840 { 841 LOGV("AddCmdToQueue"); 842 if (aType == DATA_EVENT) { 843 LOGE("Invalid argument"); 844 OSCL_LEAVE(OsclErrArgument); 845 return -1; 846 } 847 848 AndroidCameraInputCmd cmd; 849 cmd.iType = aType; 850 cmd.iContext = OSCL_STATIC_CAST(OsclAny*, aContext); 851 cmd.iData = aData; 852 cmd.iId = iCmdIdCounter; 853 ++iCmdIdCounter; 854 855 // TODO: 856 // Check against out of memory failure 857 int err = 0; 858 OSCL_TRY(err, iCmdQueue.push_back(cmd)); 859 OSCL_FIRST_CATCH_ANY(err, LOGE("Out of memory"); return -1;); 860 RunIfNotReady(); 861 return cmd.iId; 862 } 863 864 void AndroidCameraInput::AddDataEventToQueue(uint32 aMicroSecondsToEvent) 865 { 866 LOGV("AddDataEventToQueue"); 867 AndroidCameraInputCmd cmd; 868 cmd.iType = DATA_EVENT; 869 870 int err = 0; 871 OSCL_TRY(err, iCmdQueue.push_back(cmd)); 872 OSCL_FIRST_CATCH_ANY(err, LOGE("Out of memory"); return;); 873 RunIfNotReady(aMicroSecondsToEvent); 874 } 875 876 void AndroidCameraInput::DoRequestCompleted(const AndroidCameraInputCmd& aCmd, PVMFStatus aStatus, OsclAny* aEventData) 877 { 878 LOGV("DoRequestCompleted"); 879 PVMFCmdResp response(aCmd.iId, aCmd.iContext, aStatus, aEventData); 880 881 for (uint32 i = 0; i < iObservers.size(); i++) { 882 iObservers[i]->RequestCompleted(response); 883 } 884 } 885 886 PVMFStatus AndroidCameraInput::DoInit() 887 { 888 LOGV("DoInit()"); 889 iState = STATE_INITIALIZED; 890 iMilliSecondsPerDataEvent = (int32)(1000 / mFrameRate); 891 iMicroSecondsPerDataEvent = (int32)(1000000 / mFrameRate); 892 iDataEventCounter = 0; 893 894 // create a camera if the app didn't supply one 895 if (mCamera == 0) { 896 mCamera = Camera::connect(); 897 } 898 899 // always call setPreviewDisplay() regardless whether mCamera is just created or not 900 // return failure if no display surface is available 901 if (mCamera != NULL && mSurface != NULL) { 902 mCamera->setPreviewDisplay(mSurface); 903 } else { 904 if (mCamera == NULL) { 905 LOGE("Camera is not available"); 906 } else if (mSurface == NULL) { 907 LOGE("No surface is available for display"); 908 } 909 return PVMFFailure; 910 } 911 912 LOGD("Intended mFrameWidth=%d, mFrameHeight=%d ",mFrameWidth, mFrameHeight); 913 String8 s = mCamera->getParameters(); 914 if (s.length() == 0) { 915 LOGE("Failed to get camera(%p) parameters", mCamera.get()); 916 return PVMFFailure; 917 } 918 CameraParameters p(s); 919 p.setPreviewSize(mFrameWidth, mFrameHeight); 920 p.setPreviewFrameRate(mFrameRate); 921 s = p.flatten(); 922 if (mCamera->setParameters(s) != NO_ERROR) { 923 LOGE("Failed to set camera(%p) parameters", mCamera.get()); 924 return PVMFFailure; 925 } 926 927 // Since we may not honor the preview size that app has requested 928 // It is a good idea to get the actual preview size and used it 929 // for video recording. 930 CameraParameters newCameraParam(mCamera->getParameters()); 931 int32 width, height; 932 newCameraParam.getPreviewSize(&width, &height); 933 if (width < 0 || height < 0) { 934 LOGE("Failed to get camera(%p) preview size", mCamera.get()); 935 return PVMFFailure; 936 } 937 if (width != mFrameWidth || height != mFrameHeight) { 938 LOGE("Mismatch between the intended frame size (%dx%d) and the available frame size (%dx%d)", mFrameWidth, mFrameHeight, width, height); 939 return PVMFFailure; 940 } 941 LOGD("Actual mFrameWidth=%d, mFrameHeight=%d ",mFrameWidth, mFrameHeight); 942 if (mCamera->startPreview() != NO_ERROR) { 943 LOGE("Failed to start camera(%p) preview", mCamera.get()); 944 return PVMFFailure; 945 } 946 return PVMFSuccess; 947 } 948 949 PVMFStatus AndroidCameraInput::DoStart() 950 { 951 LOGV("DoStart"); 952 953 iAudioFirstFrameTs = 0; 954 // Set the clock state observer 955 if (iAuthorClock) { 956 iAuthorClock->ConstructMediaClockNotificationsInterface(iClockNotificationsInf, *this); 957 958 if (iClockNotificationsInf == NULL) { 959 return PVMFErrNoMemory; 960 } 961 962 iClockNotificationsInf->SetClockStateObserver(*this); 963 } 964 965 PVMFStatus status = PVMFFailure; 966 iWriteState = EWriteOK; 967 if (mCamera == NULL) { 968 status = PVMFFailure; 969 LOGE("mCamera is not initialized yet"); 970 } else { 971 mCamera->setListener(mListener); 972 if (mCamera->startRecording() != NO_ERROR) { 973 LOGE("mCamera start recording failed"); 974 status = PVMFFailure; 975 } else { 976 iState = STATE_STARTED; 977 status = PVMFSuccess; 978 } 979 } 980 AddDataEventToQueue(iMilliSecondsPerDataEvent); 981 return status; 982 } 983 984 PVMFStatus AndroidCameraInput::DoPause() 985 { 986 LOGV("DoPause"); 987 iState = STATE_PAUSED; 988 return PVMFSuccess; 989 } 990 991 // Does this work for reset? 992 PVMFStatus AndroidCameraInput::DoReset() 993 { 994 LOGD("DoReset: E"); 995 // Remove and destroy the clock state observer 996 RemoveDestroyClockObs(); 997 iDataEventCounter = 0; 998 iAudioLossDuration = 0; 999 iWriteState = EWriteOK; 1000 if ( (iState == STATE_STARTED) || (iState == STATE_PAUSED) ) { 1001 if (mCamera != NULL) { 1002 mCamera->setListener(NULL); 1003 mCamera->stopRecording(); 1004 ReleaseQueuedFrames(); 1005 } 1006 } 1007 while(!iCmdQueue.empty()) 1008 { 1009 AndroidCameraInputCmd cmd = iCmdQueue[0]; 1010 iCmdQueue.erase(iCmdQueue.begin()); 1011 } 1012 Cancel(); 1013 iState = STATE_IDLE; 1014 LOGD("DoReset: X"); 1015 return PVMFSuccess; 1016 } 1017 1018 PVMFStatus AndroidCameraInput::DoFlush(const AndroidCameraInputCmd& aCmd) 1019 { 1020 LOGV("DoFlush"); 1021 // This method should stop capturing media data but continue to send 1022 // captured media data that is already in buffer and then go to 1023 // stopped state. 1024 // However, in this case of file input we do not have such a buffer for 1025 // captured data, so this behaves the same way as stop. 1026 return DoStop(aCmd); 1027 } 1028 1029 PVMFStatus AndroidCameraInput::DoStop(const AndroidCameraInputCmd& aCmd) 1030 { 1031 LOGD("DoStop: E"); 1032 1033 // Remove and destroy the clock state observer 1034 RemoveDestroyClockObs(); 1035 1036 iDataEventCounter = 0; 1037 iWriteState = EWriteOK; 1038 if (mCamera != NULL) { 1039 mCamera->setListener(NULL); 1040 mCamera->stopRecording(); 1041 ReleaseQueuedFrames(); 1042 } 1043 iState = STATE_STOPPED; 1044 LOGD("DoStop: X"); 1045 return PVMFSuccess; 1046 } 1047 1048 PVMFStatus AndroidCameraInput::DoRead() 1049 { 1050 LOGV("DoRead"); 1051 return PVMFSuccess; 1052 } 1053 1054 PVMFStatus AndroidCameraInput::AllocateKvp(PvmiKvp*& aKvp, 1055 PvmiKeyType aKey, 1056 int32 aNumParams) 1057 { 1058 LOGV("AllocateKvp"); 1059 uint8* buf = NULL; 1060 uint32 keyLen = oscl_strlen(aKey) + 1; 1061 int32 err = 0; 1062 1063 OSCL_TRY(err, 1064 buf = (uint8*)iAlloc.allocate(aNumParams * (sizeof(PvmiKvp) + keyLen)); 1065 if (!buf) { 1066 LOGE("Failed to allocate memory to Kvp"); 1067 OSCL_LEAVE(OsclErrNoMemory); 1068 } 1069 ); 1070 OSCL_FIRST_CATCH_ANY(err, 1071 LOGE("kvp allocation failed"); 1072 return PVMFErrNoMemory; 1073 ); 1074 1075 PvmiKvp* curKvp = aKvp = new (buf) PvmiKvp; 1076 buf += sizeof(PvmiKvp); 1077 for (int32 i = 1; i < aNumParams; ++i) { 1078 curKvp += i; 1079 curKvp = new (buf) PvmiKvp; 1080 buf += sizeof(PvmiKvp); 1081 } 1082 1083 for (int32 i = 0; i < aNumParams; ++i) { 1084 aKvp[i].key = (char*)buf; 1085 oscl_strncpy(aKvp[i].key, aKey, keyLen); 1086 buf += keyLen; 1087 } 1088 1089 return PVMFSuccess; 1090 } 1091 1092 PVMFStatus AndroidCameraInput::VerifyAndSetParameter(PvmiKvp* aKvp, 1093 bool aSetParam) 1094 { 1095 LOGV("VerifyAndSetParameter"); 1096 1097 if (!aKvp) { 1098 LOGE("Invalid key-value pair"); 1099 return PVMFFailure; 1100 } 1101 1102 if (!pv_mime_strcmp(aKvp->key, OUTPUT_FORMATS_VALTYPE)) { 1103 if(pv_mime_strcmp(aKvp->value.pChar_value, ANDROID_VIDEO_FORMAT) == 0) { 1104 return PVMFSuccess; 1105 } else { 1106 LOGE("Unsupported format %d", aKvp->value.uint32_value); 1107 return PVMFFailure; 1108 } 1109 } 1110 else if (pv_mime_strcmp(aKvp->key, PVMF_AUTHORING_CLOCK_KEY) == 0) 1111 { 1112 LOGV("AndroidCameraInput::VerifyAndSetParameter() PVMF_AUTHORING_CLOCK_KEY value %p", aKvp->value.key_specific_value); 1113 if( (NULL == aKvp->value.key_specific_value) && ( iAuthorClock ) ) 1114 { 1115 RemoveDestroyClockObs(); 1116 } 1117 iAuthorClock = (PVMFMediaClock*)aKvp->value.key_specific_value; 1118 return PVMFSuccess; 1119 } 1120 1121 LOGE("Unsupported parameter(%s)", aKvp->key); 1122 return PVMFFailure; 1123 } 1124 1125 void AndroidCameraInput::SetPreviewSurface(const sp<android::ISurface>& surface) 1126 { 1127 LOGV("SetPreviewSurface"); 1128 mSurface = surface; 1129 1130 if (mCamera != NULL) { 1131 mCamera->setPreviewDisplay(surface); 1132 } 1133 } 1134 1135 PVMFStatus AndroidCameraInput::SetCamera(const sp<android::ICamera>& camera) 1136 { 1137 LOGV("SetCamera"); 1138 mFlags &= ~ FLAGS_SET_CAMERA | FLAGS_HOT_CAMERA; 1139 if (camera == NULL) { 1140 LOGV("camera is NULL"); 1141 return PVMFErrArgument; 1142 } 1143 1144 // Connect our client to the camera remote 1145 mCamera = Camera::create(camera); 1146 if (mCamera == NULL) { 1147 LOGE("Unable to connect to camera"); 1148 return PVMFErrNoResources; 1149 } 1150 1151 LOGV("Connected to camera"); 1152 mFlags |= FLAGS_SET_CAMERA; 1153 if (mCamera->previewEnabled()) { 1154 mFlags |= FLAGS_HOT_CAMERA; 1155 LOGV("camera is hot"); 1156 } 1157 return PVMFSuccess; 1158 } 1159 1160 PVMFStatus AndroidCameraInput::postWriteAsync(nsecs_t timestamp, const sp<IMemory>& frame) 1161 { 1162 LOGV("postWriteAsync"); 1163 1164 if (frame == NULL) { 1165 LOGE("frame is a NULL pointer"); 1166 return PVMFFailure; 1167 } 1168 1169 if((!iPeer) || (!isRecorderStarting()) || (iWriteState == EWriteBusy) || (NULL == iAuthorClock) || (iAuthorClock->GetState() != PVMFMediaClock::RUNNING)) { 1170 if( NULL == iAuthorClock ) 1171 { 1172 LOGE("Recording is not ready (iPeer %p iState %d iWriteState %d iAuthorClock NULL), frame dropped", iPeer, iState, iWriteState); 1173 } 1174 else 1175 { 1176 LOGE("Recording is not ready (iPeer %p iState %d iWriteState %d iClockState %d), frame dropped", iPeer, iState, iWriteState, iAuthorClock->GetState()); 1177 } 1178 mCamera->releaseRecordingFrame(frame); 1179 return PVMFSuccess; 1180 } 1181 1182 // Now compare the video timestamp with the AudioFirstTimestamp 1183 // if video timestamp is earlier to audio drop it 1184 // or else send it downstream with correct timestamp 1185 uint32 ts = (uint32)(timestamp / 1000000L); 1186 1187 // In cases of Video Only recording iAudioFirstFrameTs will always be zero, 1188 // so for such cases assign iAudioFirstFrameTs to Video's first sample TS 1189 // which will make Video samples to start with Timestamp zero. 1190 if (iAudioFirstFrameTs == 0) 1191 iAudioFirstFrameTs = ts; 1192 1193 iAudioLossMutex.Lock(); 1194 if (ts < iAudioFirstFrameTs + iAudioLossDuration) { 1195 // Drop the frame 1196 iAudioLossMutex.Unlock(); 1197 mCamera->releaseRecordingFrame(frame); 1198 return PVMFSuccess; 1199 } else { 1200 // calculate timestamp as offset from start time plus lost audio 1201 ts -= (iAudioFirstFrameTs + iAudioLossDuration); 1202 } 1203 iAudioLossMutex.Unlock(); 1204 1205 // Determine how much video to drop so when we resync to the audio 1206 // time we don't go into old video (we need increasing timestamps) 1207 if (ts <= iTimeStamp) { 1208 LOGD("Dropping video frame to catch up for audio ts %lu, dropUntil %lu", ts, iTimeStamp); 1209 mCamera->releaseRecordingFrame(frame); 1210 return PVMFSuccess; 1211 } 1212 1213 // Make sure that no two samples have the same timestamp 1214 if (iDataEventCounter != 0) { 1215 if (iTimeStamp != ts) { 1216 iTimeStamp = ts; 1217 } else { 1218 ++iTimeStamp; 1219 } 1220 } 1221 1222 // get memory offset for frame buffer 1223 ssize_t offset = 0; 1224 size_t size = 0; 1225 sp<IMemoryHeap> heap = frame->getMemory(&offset, &size); 1226 LOGV("postWriteAsync: ID = %d, base = %p, offset = %ld, size = %d pointer %p", heap->getHeapID(), heap->base(), offset, size, frame->pointer()); 1227 1228 // queue data to be sent to peer 1229 AndroidCameraInputMediaData data; 1230 data.iXferHeader.seq_num = iDataEventCounter++; 1231 data.iXferHeader.timestamp = iTimeStamp; 1232 data.iXferHeader.flags = 0; 1233 data.iXferHeader.duration = 0; 1234 data.iXferHeader.stream_id = 0; 1235 data.iFrameSize = size; 1236 data.iFrameBuffer = frame; 1237 1238 // lock muteddx and queue frame buffer 1239 iFrameQueueMutex.Lock(); 1240 {//compose private data 1241 //could size be zero? 1242 if(NULL == pPmemInfo) 1243 { 1244 int iCalculateNoOfCameraPreviewBuffer = heap->getSize() / size; 1245 LOGV("heap->getSize() = %d, size of each frame= %d, iCalculateNoOfCameraPreviewBuffer = %d", heap->getSize(), size, iCalculateNoOfCameraPreviewBuffer); 1246 pPmemInfo = new CAMERA_PMEM_INFO[iCalculateNoOfCameraPreviewBuffer]; 1247 if(NULL == pPmemInfo) 1248 { 1249 LOGE("Failed to allocate the camera pmem info buffer array. iCalculateNoOfCameraPreviewBuffer %d",iCalculateNoOfCameraPreviewBuffer); 1250 iFrameQueueMutex.Unlock(); 1251 return PVMFFailure; 1252 } 1253 } 1254 1255 int iIndex = offset / size; 1256 pPmemInfo[iIndex].pmem_fd = heap->getHeapID(); 1257 pPmemInfo[iIndex].offset = offset; 1258 data.iXferHeader.private_data_ptr = ((OsclAny*)(&pPmemInfo[iIndex])); 1259 LOGV("struct size %d, pmem_info - %x, &pmem_info[iIndex] - %x, iIndex =%d, pmem_info.pmem_fd = %d, pmem_info.offset = %d", sizeof(CAMERA_PMEM_INFO), pPmemInfo, &pPmemInfo[iIndex], iIndex, pPmemInfo[iIndex].pmem_fd, pPmemInfo[iIndex].offset ); 1260 } 1261 1262 iFrameQueue.push_back(data); 1263 iFrameQueueMutex.Unlock(); 1264 RunIfNotReady(); 1265 1266 return PVMFSuccess; 1267 } 1268 1269 // Value is expected to be in ms 1270 void AndroidCameraInput::setAudioLossDuration(uint32 duration) 1271 { 1272 iAudioLossMutex.Lock(); 1273 LOGD("Update for lost audio for %lu for existing duration %lu", duration, iAudioLossDuration); 1274 iAudioLossDuration += duration; 1275 iAudioLossMutex.Unlock(); 1276 } 1277 1278 // camera callback interface 1279 void AndroidCameraInputListener::postData(int32_t msgType, const sp<IMemory>& dataPtr) 1280 { 1281 } 1282 1283 void AndroidCameraInputListener::postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) 1284 { 1285 if ((mCameraInput != NULL) && (msgType == CAMERA_MSG_VIDEO_FRAME)) { 1286 mCameraInput->postWriteAsync(timestamp, dataPtr); 1287 } 1288 } 1289 1290 void AndroidCameraInput::NotificationsInterfaceDestroyed() 1291 { 1292 iClockNotificationsInf = NULL; 1293 } 1294 1295 void AndroidCameraInput::ClockStateUpdated() 1296 { 1297 PVMFMediaClock::PVMFMediaClockState iClockState = iAuthorClock->GetState(); 1298 if ((iClockState == PVMFMediaClock::RUNNING) && (iAudioFirstFrameTs == 0)) { 1299 // Get the clock time here 1300 // this will be the time of first audio frame capture 1301 bool tmpbool = false; 1302 iAuthorClock->GetCurrentTime32(iAudioFirstFrameTs, tmpbool, PVMF_MEDIA_CLOCK_MSEC); 1303 LOGV("Audio first ts %d", iAudioFirstFrameTs); 1304 } 1305 } 1306 1307 void AndroidCameraInput::RemoveDestroyClockObs() 1308 { 1309 if (iAuthorClock != NULL) { 1310 if (iClockNotificationsInf != NULL) { 1311 iClockNotificationsInf->RemoveClockStateObserver(*this); 1312 iAuthorClock->DestroyMediaClockNotificationsInterface(iClockNotificationsInf); 1313 iClockNotificationsInf = NULL; 1314 } 1315 } 1316 } 1317 1318 1319