mediametadataretriever.cpp revision 2729ea9262ca60d93047e984739887cfc89e82eb
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#include <media/mediametadataretriever.h>
19
20#ifdef LOG_TAG
21#undef LOG_TAG
22#define LOG_TAG "MediaMetadataRetriever"
23#endif
24
25#include <utils/Log.h>
26#include <dlfcn.h>
27
28namespace android {
29
30// Factory class function in shared libpvplayer.so
31typedef MediaMetadataRetrieverImpl* (*createRetriever_f)();
32
33MediaMetadataRetrieverImpl *MediaMetadataRetriever::mRetriever = NULL;
34void                       *MediaMetadataRetriever::mLibHandler = NULL;
35
36void MediaMetadataRetriever::create()
37{
38    // Load libpvplayer library once and only once.
39    if (!mLibHandler) {
40        mLibHandler = dlopen("libopencoreplayer.so", RTLD_NOW);
41        if (!mLibHandler) {
42            LOGE("setDataSource: dlopen failed on libopencoreplayer.so");
43            return;
44        }
45    }
46
47    // Each time create a new MediaMetadataRetrieverImpl object.
48    if (mRetriever) {
49        delete mRetriever;
50    }
51    createRetriever_f createRetriever = reinterpret_cast<createRetriever_f>(dlsym(mLibHandler, "createRetriever"));
52    if (!createRetriever) {
53        LOGE("setDataSource: dlsym failed on createRetriever in libpvplayer.so");
54        return;
55    }
56    mRetriever = createRetriever();
57    if (!mRetriever) {
58        LOGE("setDataSource: createRetriever failed in libpvplayer.so");
59    }
60}
61
62status_t MediaMetadataRetriever::setDataSource(const char* srcUrl)
63{
64    if (srcUrl == NULL) {
65        return UNKNOWN_ERROR;
66    }
67
68    if (mRetriever) {
69        return mRetriever->setDataSource(srcUrl);
70    }
71    return UNKNOWN_ERROR;
72}
73
74const char* MediaMetadataRetriever::extractMetadata(int keyCode)
75{
76    if (mRetriever) {
77        return mRetriever->extractMetadata(keyCode);
78    }
79    return NULL;
80}
81
82MediaAlbumArt* MediaMetadataRetriever::extractAlbumArt()
83{
84    if (mRetriever) {
85        return mRetriever->extractAlbumArt();
86    }
87    return NULL;
88}
89
90SkBitmap* MediaMetadataRetriever::captureFrame()
91{
92    if (mRetriever) {
93        return mRetriever->captureFrame();
94    }
95    return NULL;
96}
97
98void MediaMetadataRetriever::setMode(int mode)
99{
100    if (mRetriever) {
101        mRetriever->setMode(mode);
102    }
103}
104
105void MediaMetadataRetriever::release()
106{
107    if (!mLibHandler) {
108        dlclose(mLibHandler);
109        mLibHandler = NULL;
110    }
111    if (!mRetriever) {
112        delete mRetriever;
113        mRetriever = NULL;
114    }
115}
116
117void MediaAlbumArt::clearData() {
118    if (data != NULL) {
119        delete []data;
120        data = NULL;
121    }
122    length = 0;
123}
124
125
126MediaAlbumArt::MediaAlbumArt(const char* url)
127{
128    length = 0;
129    data = NULL;
130    FILE *in = fopen(url, "r");
131    if (!in) {
132        LOGE("extractExternalAlbumArt: Failed to open external album art url: %s.", url);
133        return;
134    }
135    fseek(in, 0, SEEK_END);
136    length = ftell(in);  // Allocating buffer of size equals to the external file size.
137    if (length == 0 || (data = new char[length]) == NULL) {
138        if (length == 0) {
139            LOGE("extractExternalAlbumArt: External album art url: %s has a size of 0.", url);
140        } else if (data == NULL) {
141            LOGE("extractExternalAlbumArt: No enough memory for storing the retrieved album art.");
142            length = 0;
143        }
144        fclose(in);
145        return;
146    }
147    rewind(in);
148    if (fread(data, 1, length, in) != length) {  // Read failed.
149        length = 0;
150        delete []data;
151        data = NULL;
152        LOGE("extractExternalAlbumArt: Failed to retrieve the contents of an external album art.");
153    }
154    fclose(in);
155}
156
157status_t MediaAlbumArt::setData(unsigned int len, const char* buf) {
158    clearData();
159    length = len;
160    data = copyData(len, buf);
161    return (data != NULL)? OK: UNKNOWN_ERROR;
162}
163
164char* MediaAlbumArt::copyData(unsigned int len, const char* buf) {
165    if (len == 0 || !buf) {
166        if (len == 0) {
167            LOGE("copyData: Length is 0.");
168        } else if (!buf) {
169            LOGE("copyData: buf is NULL pointer");
170        }
171        return NULL;
172    }
173    char* copy = new char[len];
174    if (!copy) {
175        LOGE("copyData: No enough memory to copy out the data.");
176        return NULL;
177    }
178    memcpy(copy, buf, len);
179    return copy;
180}
181
182}; // namespace android
183