Home | History | Annotate | Download | only in android
      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