1 /* 2 ** 3 ** Copyright 2008, The Android Open Source Project 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 #undef LOG_TAG 20 #define LOG_TAG "MetadataDriver" 21 #include <utils/Log.h> 22 23 #include <media/thread_init.h> 24 #include <core/SkBitmap.h> 25 #include <private/media/VideoFrame.h> 26 27 #include "metadatadriver.h" 28 29 using namespace android; 30 31 const char* MetadataDriver::ALBUM_ART_KEY = "graphic"; 32 33 const char* MetadataDriver::METADATA_KEYS[NUM_METADATA_KEYS] = { 34 "track-info/track-number", 35 "album", 36 "artist", 37 "author", 38 "composer", 39 "date", 40 "genre", 41 "title", 42 "year", 43 "duration", 44 "num-tracks", 45 "drm/is-protected", 46 "track-info/codec-name", 47 "rating", 48 "comment", 49 "copyright", 50 "track-info/bit-rate", 51 "track-info/frame-rate", 52 "track-info/video/format", 53 "track-info/video/height", 54 "track-info/video/width", 55 "writer", 56 }; 57 58 static void dumpkeystolog(PVPMetadataList list) 59 { 60 LOGV("dumpkeystolog"); 61 uint32 n = list.size(); 62 for(uint32 i = 0; i < n; ++i) { 63 LOGI("@@@@@ wma key: %s", list[i].get_cstr()); 64 } 65 } 66 67 MetadataDriver::MetadataDriver(uint32 mode): OsclActiveObject(OsclActiveObject::EPriorityNominal, "MetadataDriver") 68 { 69 LOGV("constructor"); 70 mMode = mode; 71 mUtil = NULL; 72 mDataSource = NULL; 73 #if BEST_THUMBNAIL_MODE 74 mLocalDataSource = NULL; 75 #endif 76 mCmdId = 0; 77 mContextObjectRefValue = 0x5C7A; // Some random number 78 mContextObject = mContextObjectRefValue; 79 mMediaAlbumArt = NULL; 80 mSharedFd = -1; 81 mVideoFrame = NULL; 82 for (uint32 i = 0; i < NUM_METADATA_KEYS; ++i) { 83 mMetadataValues[i][0] = '\0'; 84 } 85 LOGV("constructor: Mode (%d).", mMode); 86 } 87 88 /*static*/ int MetadataDriver::startDriverThread(void *cookie) 89 { 90 LOGV("startDriverThread"); 91 MetadataDriver *driver = (MetadataDriver *)cookie; 92 return driver->retrieverThread(); 93 } 94 95 int MetadataDriver::retrieverThread() 96 { 97 LOGV("retrieverThread"); 98 if (!InitializeForThread()) { 99 LOGV("InitializeForThread fail"); 100 mSyncSem->Signal(); 101 return -1; 102 } 103 104 OMX_MasterInit(); 105 OsclScheduler::Init("PVAuthorEngineWrapper"); 106 mState = STATE_CREATE; 107 AddToScheduler(); 108 RunIfNotReady(); 109 OsclExecScheduler *sched = OsclExecScheduler::Current(); 110 111 { 112 OsclLeaveCode error = OsclErrNone; 113 OSCL_TRY(error, sched->StartScheduler()); 114 OSCL_FIRST_CATCH_ANY(error, 115 // Some AO did a leave, log it 116 LOGE("Ln %d Player Engine AO did a leave, error=%d", __LINE__, error) 117 ); 118 } 119 120 mSyncSem->Signal(); // Signal that doSetDataSource() is done. 121 OsclScheduler::Cleanup(); 122 OMX_MasterDeinit(); 123 UninitializeForThread(); 124 return 0; 125 } 126 127 MetadataDriver::~MetadataDriver() 128 { 129 LOGV("destructor"); 130 131 mCmdId = 0; 132 delete mVideoFrame; 133 mVideoFrame = NULL; 134 delete mMediaAlbumArt; 135 mMediaAlbumArt = NULL; 136 delete mSyncSem; 137 mSyncSem = NULL; 138 139 closeSharedFdIfNecessary(); 140 } 141 142 const char* MetadataDriver::extractMetadata(int keyCode) 143 { 144 LOGV("extractMetadata"); 145 char *value = NULL; 146 if (mMode & GET_METADATA_ONLY) { 147 // Comparing int with unsigned int 148 if (keyCode < 0 || keyCode >= (int) NUM_METADATA_KEYS) { 149 LOGE("extractMetadata: Invalid keyCode: %d.", keyCode); 150 } else { 151 value = mMetadataValues[keyCode]; 152 } 153 } 154 if (value == NULL || value[0] == '\0') { 155 return NULL; 156 } 157 return value; 158 } 159 160 MediaAlbumArt *MetadataDriver::extractAlbumArt() 161 { 162 LOGV("extractAlbumArt"); 163 if (mMode & GET_METADATA_ONLY) { // copy out 164 if (mMediaAlbumArt != NULL && mMediaAlbumArt->mSize > 0) { 165 return new MediaAlbumArt(*mMediaAlbumArt); 166 } else { 167 LOGE("failed to extract album art"); 168 return NULL; 169 } 170 } 171 LOGE("extractAlbumArt: invalid mode (%d) to extract album art", mMode); 172 return NULL; 173 } 174 175 // How to better manage these constant strings? 176 bool MetadataDriver::containsSupportedKey(const OSCL_HeapString<OsclMemAllocator>& str) const 177 { 178 LOGV("containsSupportedKey"); 179 const char* cStr = str.get_cstr(); 180 for (uint32 i = 0; i < NUM_METADATA_KEYS; ++i) { 181 if (strcasestr(cStr, METADATA_KEYS[i])) { 182 return true; 183 } 184 } 185 186 // Key "graphic" is a special metadata key for retrieving album art image. 187 if (strcasestr(cStr, "graphic")) { 188 return true; 189 } 190 return false; 191 } 192 193 // Delete unnecessary keys before retrieving the metadata values to avoid 194 // retrieving all metadata values for all metadata keys 195 void MetadataDriver::trimKeys() 196 { 197 LOGV("trimKeys"); 198 //dumpkeystolog(mMetadataKeyList); 199 mActualMetadataKeyList.clear(); 200 uint32 n = mMetadataKeyList.size(); 201 mActualMetadataKeyList.reserve(n); 202 for (uint32 i = 0; i < n; ++i) { 203 if (containsSupportedKey(mMetadataKeyList[i])) { 204 mActualMetadataKeyList.push_back(mMetadataKeyList[i]); 205 } 206 } 207 mMetadataKeyList.clear(); 208 } 209 210 // Returns: 211 // 1. UNKNOWN_ERROR 212 // a. If the metadata value(s) is too long, and cannot be hold in valueLength bytes 213 // b. If nothing is found 214 // 2. OK 215 // a. If metadata value(s) is found 216 status_t MetadataDriver::extractMetadata(const char* key, char* value, uint32 valueLength) 217 { 218 LOGV("extractMetadata"); 219 bool found = false; 220 value[0] = '\0'; 221 for (uint32 i = 0, n = mMetadataValueList.size(); i < n; ++i) { 222 if (0 == strncasecmp(mMetadataValueList[i].key, key, strlen(key))) { 223 found = true; 224 switch(GetValTypeFromKeyString(mMetadataValueList[i].key)) { 225 case PVMI_KVPVALTYPE_CHARPTR: { 226 uint32 length = oscl_strlen(mMetadataValueList[i].value.pChar_value) + 1; 227 if (length > valueLength) { 228 return UNKNOWN_ERROR; 229 } 230 oscl_snprintf(value, length, "%s", mMetadataValueList[i].value.pChar_value); 231 break; 232 } 233 case PVMI_KVPVALTYPE_WCHARPTR: { 234 // Assume string is in UCS-2 encoding so convert to UTF-8. 235 uint32 length = oscl_strlen(mMetadataValueList[i].value.pWChar_value) + 1; 236 if (length > valueLength) { 237 return UNKNOWN_ERROR; 238 } 239 length = oscl_UnicodeToUTF8(mMetadataValueList[i].value.pWChar_value, length, value, valueLength); 240 break; 241 } 242 case PVMI_KVPVALTYPE_UINT32: { 243 // FIXME: 244 // This is an ugly hack since OpenCore returns duration in the following two formats: 245 // 1. duration;valtype=uint32 (the duration is an integer representing milliseconds) 246 // 2. duration;valtype=uint32;timescale=8000 (the duration is an integer representing the 247 // duration in a timescale of 8 kHz) 248 // It would be nice to have OpenCore always return duration in the first format. 249 // PV will study on fixing this to always return duration in the first format. 250 // Until that fix is available, we still need to do this. 251 const char* durKeyStr = "duration"; 252 const char* timeScaleStr = "timescale="; 253 int timescale = 1000; 254 if (strncasecmp(key, durKeyStr, strlen(durKeyStr)) == 0) { 255 char *p; 256 if ((p = strcasestr(mMetadataValueList[i].key, timeScaleStr)) != NULL) { 257 timescale = atoi(p + strlen(timeScaleStr)); 258 } 259 } 260 int duration = (mMetadataValueList[i].value.uint32_value * 1000LL) / timescale; 261 oscl_snprintf(value, valueLength, "%d", duration); 262 break; 263 } 264 case PVMI_KVPVALTYPE_INT32: 265 oscl_snprintf(value, valueLength, "%d", mMetadataValueList[i].value.int32_value); 266 break; 267 268 case PVMI_KVPVALTYPE_UINT8: 269 oscl_snprintf(value, valueLength, "%d", mMetadataValueList[i].value.uint8_value); 270 break; 271 272 case PVMI_KVPVALTYPE_FLOAT: 273 oscl_snprintf(value, valueLength, "%f", mMetadataValueList[i].value.float_value); 274 break; 275 276 case PVMI_KVPVALTYPE_DOUBLE: 277 oscl_snprintf(value, valueLength, "%f", mMetadataValueList[i].value.double_value); 278 break; 279 280 case PVMI_KVPVALTYPE_BOOL: 281 oscl_snprintf(value, valueLength, "%s", mMetadataValueList[i].value.bool_value? "true": "false"); 282 break; 283 284 default: 285 return UNKNOWN_ERROR; 286 } 287 288 LOGV("value is: %s.", value); 289 290 break; 291 } 292 } 293 return found? OK: UNKNOWN_ERROR; 294 } 295 296 void MetadataDriver::cacheMetadataRetrievalResults() 297 { 298 LOGV("cacheMetadataRetrievalResults"); 299 #if _METADATA_DRIVER_INTERNAL_DEBUG_ENABLE_ 300 for (uint32 i = 0, n = mMetadataValueList.size(); i < n; ++i) { 301 LOGV("Value %d: Key string: %s.", (i+1), mMetadataValueList[i].key); 302 } 303 #endif 304 for (uint32 i = 0; i < NUM_METADATA_KEYS; ++i) { 305 LOGV("extract metadata key: %s", METADATA_KEYS[i]); 306 extractMetadata(METADATA_KEYS[i], mMetadataValues[i], MAX_METADATA_STRING_LENGTH - 1); 307 } 308 doExtractAlbumArt(); 309 } 310 311 status_t MetadataDriver::extractEmbeddedAlbumArt(const PvmfApicStruct* apic) 312 { 313 LOGV("extractEmbeddedAlbumArt"); 314 char* buf = (char*) apic->iGraphicData; 315 uint32 size = apic->iGraphicDataLen; 316 LOGV("extractEmbeddedAlbumArt: Embedded graphic or album art (%d bytes) is found.", size); 317 if (size && buf) { 318 delete mMediaAlbumArt; 319 mMediaAlbumArt = new MediaAlbumArt(); 320 if (mMediaAlbumArt == NULL) { 321 LOGE("extractEmbeddedAlbumArt: Not enough memory to hold a MediaAlbumArt object"); 322 return NO_MEMORY; 323 } 324 mMediaAlbumArt->mSize = size; 325 mMediaAlbumArt->mData = new uint8[size]; 326 if (mMediaAlbumArt->mData == NULL) { 327 LOGE("extractEmbeddedAlbumArt: Not enough memory to hold the binary data of a MediaAlbumArt object"); 328 delete mMediaAlbumArt; 329 mMediaAlbumArt = NULL; 330 return NO_MEMORY; 331 } 332 memcpy(mMediaAlbumArt->mData, buf, size); 333 return NO_ERROR; 334 } 335 return BAD_VALUE; 336 } 337 338 status_t MetadataDriver::extractExternalAlbumArt(const char* url) 339 { 340 LOGV("extractExternalAlbumArt: External graphic or album art is found: %s.", url); 341 delete mMediaAlbumArt; 342 mMediaAlbumArt = new MediaAlbumArt(url); 343 return (mMediaAlbumArt && mMediaAlbumArt->mSize > 0)? OK: BAD_VALUE; 344 } 345 346 // Finds the first album art and extract it. 347 status_t MetadataDriver::doExtractAlbumArt() 348 { 349 LOGV("doExtractAlbumArt"); 350 status_t status = UNKNOWN_ERROR; 351 for (uint32 i = 0, n = mMetadataValueList.size(); i < n; ++i) { 352 if (strcasestr(mMetadataValueList[i].key, ALBUM_ART_KEY)) { 353 LOGV("doExtractAlbumArt: album art key: %s", mMetadataValueList[i].key); 354 if (PVMI_KVPVALTYPE_KSV == GetValTypeFromKeyString(mMetadataValueList[i].key)) { 355 const char* embeddedKey = "graphic;format=APIC;valtype=ksv"; 356 const char* externalKey = "graphic;valtype=char*"; 357 if (strstr(mMetadataValueList[i].key, embeddedKey) && mMetadataValueList[i].value.key_specific_value) { 358 // Embedded album art. 359 status = extractEmbeddedAlbumArt(((PvmfApicStruct*)mMetadataValueList[i].value.key_specific_value)); 360 } else if (strstr(mMetadataValueList[i].key, externalKey)) { 361 // Album art linked with an external url. 362 status = extractExternalAlbumArt(mMetadataValueList[i].value.pChar_value); 363 } 364 365 if (status != OK) { 366 continue; 367 } 368 return status; // Found the album art. 369 } 370 } 371 } 372 return UNKNOWN_ERROR; 373 } 374 375 void MetadataDriver::clearCache() 376 { 377 LOGV("clearCache"); 378 delete mVideoFrame; 379 mVideoFrame = NULL; 380 delete mMediaAlbumArt; 381 mMediaAlbumArt = NULL; 382 for(uint32 i = 0; i < NUM_METADATA_KEYS; ++i) { 383 mMetadataValues[i][0] = '\0'; 384 } 385 } 386 387 status_t MetadataDriver::setDataSourceFd( 388 int fd, int64_t offset, int64_t length) { 389 LOGV("setDataSourceFd"); 390 391 closeSharedFdIfNecessary(); 392 393 if (offset < 0 || length < 0) { 394 if (offset < 0) { 395 LOGE("negative offset (%lld)", offset); 396 } 397 if (length < 0) { 398 LOGE("negative length (%lld)", length); 399 } 400 return INVALID_OPERATION; 401 } 402 403 mSharedFd = dup(fd); 404 405 char url[80]; 406 sprintf(url, "sharedfd://%d:%lld:%lld", mSharedFd, offset, length); 407 408 clearCache(); 409 return doSetDataSource(url); 410 } 411 412 status_t MetadataDriver::setDataSource(const char* srcUrl) 413 { 414 LOGV("setDataSource"); 415 416 closeSharedFdIfNecessary(); 417 418 // Don't let somebody trick us in to reading some random block of memory. 419 if (strncmp("sharedfd://", srcUrl, 11) == 0) { 420 LOGE("setDataSource: Invalid url (%s).", srcUrl); 421 return UNKNOWN_ERROR; 422 } 423 424 if (oscl_strlen(srcUrl) > MAX_STRING_LENGTH) { 425 LOGE("setDataSource: Data source url length (%d) is too long.", oscl_strlen(srcUrl)); 426 return UNKNOWN_ERROR; 427 } 428 clearCache(); 429 return doSetDataSource(srcUrl); 430 } 431 432 status_t MetadataDriver::doSetDataSource(const char* dataSrcUrl) 433 { 434 LOGV("doSetDataSource"); 435 if (mMode & GET_FRAME_ONLY) { 436 #if BEST_THUMBNAIL_MODE 437 mFrameSelector.iSelectionMethod = PVFrameSelector::SPECIFIC_FRAME; 438 mFrameSelector.iFrameInfo.iTimeOffsetMilliSec = 0; 439 #else 440 mFrameSelector.iSelectionMethod=PVFrameSelector::SPECIFIC_FRAME; 441 mFrameSelector.iFrameInfo.iFrameIndex=0; 442 #endif 443 } 444 mIsSetDataSourceSuccessful = false; 445 oscl_wchar tmpWCharBuf[MAX_STRING_LENGTH]; 446 oscl_UTF8ToUnicode(dataSrcUrl, oscl_strlen(dataSrcUrl), tmpWCharBuf, sizeof(tmpWCharBuf)); 447 mDataSourceUrl.set(tmpWCharBuf, oscl_strlen(tmpWCharBuf)); 448 mSyncSem = new OsclSemaphore(); 449 mSyncSem->Create(); 450 createThreadEtc(MetadataDriver::startDriverThread, this, "PVMetadataRetriever"); 451 mSyncSem->Wait(); 452 return mIsSetDataSourceSuccessful? OK: UNKNOWN_ERROR; 453 } 454 455 VideoFrame* MetadataDriver::captureFrame() 456 { 457 LOGV("captureFrame"); 458 if (mMode & GET_FRAME_ONLY) { // copy out 459 if (mVideoFrame != NULL && mVideoFrame->mSize > 0) { 460 return new VideoFrame(*mVideoFrame); 461 } else { 462 LOGE("failed to capture frame"); 463 return NULL; 464 } 465 } 466 LOGE("captureFrame: invalid mode (%d) to capture a frame", mMode); 467 return NULL; 468 } 469 470 void MetadataDriver::doColorConversion() 471 { 472 LOGV("doColorConversion"); 473 // Do color conversion using PV's color conversion utility 474 int width = mFrameBufferProp.iFrameWidth; 475 int height = mFrameBufferProp.iFrameHeight; 476 int displayWidth = mFrameBufferProp.iDisplayWidth; 477 int displayHeight = mFrameBufferProp.iDisplayHeight; 478 SkBitmap *bitmap = new SkBitmap(); 479 if (!bitmap) { 480 LOGE("doColorConversion: cannot instantiate a SkBitmap object."); 481 return; 482 } 483 bitmap->setConfig(SkBitmap::kRGB_565_Config, displayWidth, displayHeight); 484 if (!bitmap->allocPixels()) { 485 LOGE("allocPixels failed"); 486 delete bitmap; 487 return; 488 } 489 490 // When passing parameters in Init call of ColorConverter library 491 // we need to take care of passing even width and height to the CC. 492 // If Width is odd then making it even as below 493 // will reduce the pitch by 1. This may result in a tilted image for 494 // clips with odd width. 495 ColorConvertBase* colorConverter = ColorConvert16::NewL(); 496 if (!colorConverter || 497 !colorConverter->Init(((width)&(~1)), ((height)&(~1)), ((width)&(~1)), displayWidth, ((displayHeight)&(~1)), ((displayWidth)&(~1)), CCROTATE_NONE) || 498 //!colorConverter->Init(width, height, width, displayWidth, displayHeight, displayWidth, CCROTATE_NONE) || 499 !colorConverter->SetMode(1) || 500 !colorConverter->Convert(mFrameBuffer, (uint8*)bitmap->getPixels())) { 501 LOGE("failed to do color conversion"); 502 delete colorConverter; 503 delete bitmap; 504 return; 505 } 506 delete colorConverter; 507 508 // Store the SkBitmap pixels in a private shared structure with known 509 // internal memory layout so that the pixels can be sent across the 510 // binder interface 511 delete mVideoFrame; 512 mVideoFrame = new VideoFrame(); 513 if (!mVideoFrame) { 514 LOGE("failed to allocate memory for a VideoFrame object"); 515 delete bitmap; 516 return; 517 } 518 mVideoFrame->mWidth = width; 519 mVideoFrame->mHeight = height; 520 mVideoFrame->mDisplayWidth = displayWidth; 521 mVideoFrame->mDisplayHeight = displayHeight; 522 mVideoFrame->mSize = bitmap->getSize(); 523 LOGV("display width (%d) and height (%d), and size (%d)", displayWidth, displayHeight, mVideoFrame->mSize); 524 mVideoFrame->mData = new uint8[mVideoFrame->mSize]; 525 if (!mVideoFrame->mData) { 526 LOGE("doColorConversion: cannot allocate buffer to hold SkBitmap pixels"); 527 delete bitmap; 528 delete mVideoFrame; 529 mVideoFrame = NULL; 530 return; 531 } 532 memcpy(mVideoFrame->mData, (uint8*) bitmap->getPixels(), mVideoFrame->mSize); 533 delete bitmap; 534 } 535 536 // Instantiate a frame and metadata utility object. 537 void MetadataDriver::handleCreate() 538 { 539 LOGV("handleCreate"); 540 int error = 0; 541 OSCL_TRY(error, mUtil = PVFrameAndMetadataFactory::CreateFrameAndMetadataUtility((char*)PVMF_MIME_YUV420, this, this, this, false)); 542 if (error || mUtil->SetMode(PV_FRAME_METADATA_INTERFACE_MODE_SOURCE_METADATA_AND_THUMBNAIL) != PVMFSuccess) { 543 handleCommandFailure(); 544 } else { 545 mState = STATE_ADD_DATA_SOURCE; 546 RunIfNotReady(); 547 } 548 } 549 550 // Create a data source and add it. 551 void MetadataDriver::handleAddDataSource() 552 { 553 LOGV("handleAddDataSource"); 554 int error = 0; 555 mDataSource = new PVPlayerDataSourceURL; 556 if (mDataSource) { 557 mDataSource->SetDataSourceURL(mDataSourceUrl); 558 mDataSource->SetDataSourceFormatType((char*)PVMF_MIME_FORMAT_UNKNOWN); 559 if (mMode & GET_FRAME_ONLY) { 560 #if BEST_THUMBNAIL_MODE 561 // Set the intent to thumbnails. 562 mLocalDataSource = new PVMFLocalDataSource(); 563 mLocalDataSource->iIntent = BITMASK_PVMF_SOURCE_INTENT_THUMBNAILS; 564 mDataSource->SetDataSourceContextData((OsclAny*)mLocalDataSource); 565 #endif 566 } 567 OSCL_TRY(error, mCmdId = mUtil->AddDataSource(*mDataSource, (OsclAny*)&mContextObject)); 568 OSCL_FIRST_CATCH_ANY(error, handleCommandFailure()); 569 } 570 } 571 572 void MetadataDriver::handleRemoveDataSource() 573 { 574 LOGV("handleRemoveDataSource"); 575 int error = 0; 576 OSCL_TRY(error, mCmdId = mUtil->RemoveDataSource(*mDataSource, (OsclAny*)&mContextObject)); 577 OSCL_FIRST_CATCH_ANY(error, handleCommandFailure()); 578 } 579 580 // Clean up, due to either failure or task completion. 581 void MetadataDriver::handleCleanUp() 582 { 583 LOGV("handleCleanUp"); 584 if (mUtil) 585 { 586 PVFrameAndMetadataFactory::DeleteFrameAndMetadataUtility(mUtil); 587 mUtil = NULL; 588 } 589 #if BEST_THUMBNAIL_MODE 590 delete mLocalDataSource; 591 mLocalDataSource = NULL; 592 #endif 593 delete mDataSource; 594 mDataSource = NULL; 595 596 OsclExecScheduler *sched=OsclExecScheduler::Current(); 597 if (sched) { 598 sched->StopScheduler(); 599 } 600 } 601 602 // Retrieve all the available metadata keys. 603 void MetadataDriver::handleGetMetadataKeys() 604 { 605 LOGV("handleGetMetadataKeys"); 606 int error = 0; 607 mMetadataKeyList.clear(); 608 OSCL_TRY(error, mCmdId = mUtil->GetMetadataKeys(mMetadataKeyList, 0, -1, NULL, (OsclAny*)&mContextObject)); 609 OSCL_FIRST_CATCH_ANY(error, handleCommandFailure()); 610 } 611 612 // Retrieve a frame and store the contents into an internal buffer. 613 void MetadataDriver::handleGetFrame() 614 { 615 LOGV("handleGetFrame"); 616 int error = 0; 617 mFrameBufferSize = MAX_VIDEO_FRAME_SIZE; 618 OSCL_TRY(error, mCmdId = mUtil->GetFrame(mFrameSelector, mFrameBuffer, mFrameBufferSize, mFrameBufferProp, (OsclAny*)&mContextObject)); 619 OSCL_FIRST_CATCH_ANY(error, handleCommandFailure()); 620 } 621 622 // Retrieve all the available metadata values associated with the given keys. 623 void MetadataDriver::handleGetMetadataValues() 624 { 625 LOGV("handleGetMetadataValues"); 626 int error = 0; 627 mNumMetadataValues = 0; 628 mMetadataValueList.clear(); 629 trimKeys(); // Switch to use actual supported key list. 630 OSCL_TRY(error, mCmdId = mUtil->GetMetadataValues(mActualMetadataKeyList, 0, -1, mNumMetadataValues, mMetadataValueList, (OsclAny*)&mContextObject)); 631 OSCL_FIRST_CATCH_ANY(error, handleCommandFailure()); 632 } 633 634 void MetadataDriver::Run() 635 { 636 LOGV("Run (%d)", mState); 637 switch(mState) { 638 case STATE_CREATE: 639 handleCreate(); 640 break; 641 case STATE_ADD_DATA_SOURCE: 642 handleAddDataSource(); 643 break; 644 case STATE_GET_METADATA_KEYS: 645 handleGetMetadataKeys(); 646 break; 647 case STATE_GET_METADATA_VALUES: 648 handleGetMetadataValues(); 649 break; 650 case STATE_GET_FRAME: 651 handleGetFrame(); 652 break; 653 case STATE_REMOVE_DATA_SOURCE: 654 handleRemoveDataSource(); 655 break; 656 default: 657 handleCleanUp(); 658 break; 659 } 660 } 661 662 bool MetadataDriver::isCommandSuccessful(const PVCmdResponse& aResponse) const 663 { 664 LOGV("isCommandSuccessful"); 665 bool success = ((aResponse.GetCmdId() == mCmdId) && 666 (aResponse.GetCmdStatus() == PVMFSuccess) && 667 (aResponse.GetContext() == (OsclAny*)&mContextObject)); 668 if (!success) { 669 LOGE("isCommandSuccessful: Command id(%d and expected %d) and status (%d and expected %d), data corruption (%s) at state (%d).", 670 aResponse.GetCmdId(), mCmdId, aResponse.GetCmdStatus(), PVMFSuccess, (aResponse.GetContext() == (OsclAny*)&mContextObject)? "false": "true", mState); 671 } 672 return success; 673 } 674 675 void MetadataDriver::handleCommandFailure() 676 { 677 LOGV("handleCommandFailure"); 678 if (mState == STATE_REMOVE_DATA_SOURCE) { 679 mState = STATE_CLEANUP_AND_COMPLETE; 680 } 681 else{ 682 mState = STATE_REMOVE_DATA_SOURCE; 683 } 684 RunIfNotReady(); 685 } 686 687 // Callback handler for a request completion by frameandmetadatautility. 688 void MetadataDriver::CommandCompleted(const PVCmdResponse& aResponse) 689 { 690 LOGV("CommandCompleted (%d)", mState); 691 if (!isCommandSuccessful(aResponse)) { 692 handleCommandFailure(); 693 return; 694 } 695 696 switch(mState) { 697 case STATE_ADD_DATA_SOURCE: 698 if (mMode & GET_METADATA_ONLY) { 699 mState = STATE_GET_METADATA_KEYS; 700 } else if (mMode & GET_FRAME_ONLY) { 701 mState = STATE_GET_FRAME; 702 } else { 703 LOGV("CommandCompleted: Neither retrieve metadata nor capture frame."); 704 mState = STATE_REMOVE_DATA_SOURCE; 705 } 706 mIsSetDataSourceSuccessful = true; 707 break; 708 case STATE_GET_METADATA_KEYS: 709 mState = STATE_GET_METADATA_VALUES; 710 break; 711 case STATE_GET_METADATA_VALUES: 712 if (mMode & GET_FRAME_ONLY) { 713 mState = STATE_GET_FRAME; 714 } else { 715 mState = STATE_REMOVE_DATA_SOURCE; 716 } 717 cacheMetadataRetrievalResults(); 718 break; 719 case STATE_GET_FRAME: 720 doColorConversion(); 721 mState = STATE_REMOVE_DATA_SOURCE; 722 break; 723 case STATE_REMOVE_DATA_SOURCE: 724 mState = STATE_CLEANUP_AND_COMPLETE; 725 break; 726 default: 727 mState = STATE_CLEANUP_AND_COMPLETE; 728 break; 729 } 730 RunIfNotReady(); 731 } 732 733 void MetadataDriver::HandleErrorEvent(const PVAsyncErrorEvent& aEvent) 734 { 735 // Error occurs, clean up and terminate. 736 LOGE("HandleErrorEvent: Event [type(%d), response type(%d)] received.", aEvent.GetEventType(), aEvent.GetResponseType()); 737 handleCommandFailure(); 738 } 739 740 741 void MetadataDriver::HandleInformationalEvent(const PVAsyncInformationalEvent& aEvent) 742 { 743 LOGV("HandleInformationalEvent: Event [type(%d), response type(%d)] received.", aEvent.GetEventType(), aEvent.GetResponseType()); 744 } 745 746 747 void MetadataDriver::closeSharedFdIfNecessary() { 748 if (mSharedFd >= 0) { 749 close(mSharedFd); 750 mSharedFd = -1; 751 } 752 } 753 754 //------------------------------------------------------------------------------ 755 #include <media/PVMetadataRetriever.h> 756 757 namespace android { 758 759 //#define LOG_NDEBUG 0 760 //#define LOG_TAG "PVMetadataRetriever" 761 762 // A concrete subclass of MediaMetadataRetrieverInterface implementation 763 // Use the MetadataDriver object as a delegate and forward related calls 764 // to the MetadataDriver object. 765 PVMetadataRetriever::PVMetadataRetriever() 766 { 767 LOGV("constructor"); 768 mMetadataDriver = new MetadataDriver(); 769 } 770 771 PVMetadataRetriever::~PVMetadataRetriever() 772 { 773 LOGV("destructor"); 774 775 Mutex::Autolock lock(mLock); 776 delete mMetadataDriver; 777 } 778 779 status_t PVMetadataRetriever::setDataSource(const char *url) 780 { 781 LOGV("setDataSource (%s)", url); 782 783 Mutex::Autolock lock(mLock); 784 if (mMetadataDriver == 0) { 785 LOGE("No MetadataDriver available"); 786 return INVALID_OPERATION; 787 } 788 if (url == 0) { 789 LOGE("Null pointer is passed as argument"); 790 return INVALID_OPERATION; 791 } 792 return mMetadataDriver->setDataSource(url); 793 } 794 795 status_t PVMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) 796 { 797 LOGV("setDataSource fd(%d), offset(%lld), length(%lld)", fd, offset, length); 798 799 Mutex::Autolock lock(mLock); 800 if (mMetadataDriver == 0) { 801 LOGE("No MetadataDriver available"); 802 return INVALID_OPERATION; 803 } 804 805 return mMetadataDriver->setDataSourceFd(fd, offset, length); 806 } 807 808 status_t PVMetadataRetriever::setMode(int mode) 809 { 810 LOGV("setMode (%d)", mode); 811 Mutex::Autolock lock(mLock); 812 if (mMetadataDriver == 0) { 813 LOGE("No MetadataDriver available"); 814 return NO_INIT; 815 } 816 if (mode < METADATA_MODE_NOOP || 817 mode > METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL) { 818 LOGE("set to invalid mode (%d)", mode); 819 return BAD_VALUE; 820 } 821 return mMetadataDriver->setMode(mode); 822 } 823 824 status_t PVMetadataRetriever::getMode(int* mode) const 825 { 826 LOGV("getMode"); 827 Mutex::Autolock lock(mLock); 828 if (mMetadataDriver == 0) { 829 LOGE("No MetadataDriver available"); 830 return INVALID_OPERATION; 831 } 832 if (mode == 0) { 833 LOGE("Null pointer is passed as argument"); 834 return INVALID_OPERATION; 835 } 836 return mMetadataDriver->getMode(mode); 837 } 838 839 VideoFrame *PVMetadataRetriever::captureFrame() 840 { 841 LOGV("captureFrame"); 842 Mutex::Autolock lock(mLock); 843 if (mMetadataDriver == 0) { 844 LOGE("No MetadataDriver available"); 845 return NULL; 846 } 847 return mMetadataDriver->captureFrame(); 848 } 849 850 MediaAlbumArt *PVMetadataRetriever::extractAlbumArt() 851 { 852 LOGV("extractAlbumArt"); 853 Mutex::Autolock lock(mLock); 854 if (mMetadataDriver == 0) { 855 LOGE("No MetadataDriver available"); 856 return NULL; 857 } 858 return mMetadataDriver->extractAlbumArt(); 859 } 860 861 const char* PVMetadataRetriever::extractMetadata(int keyCode) 862 { 863 LOGV("extractMetadata"); 864 Mutex::Autolock lock(mLock); 865 if (mMetadataDriver == 0) { 866 LOGE("No MetadataDriver available"); 867 return NULL; 868 } 869 return mMetadataDriver->extractMetadata(keyCode); 870 } 871 872 }; // android 873