The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 1 | /* |
| 2 | ** |
| 3 | ** Copyright (C) 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 | #define LOG_TAG "MetadataRetrieverClient" |
| 20 | #include <utils/Log.h> |
| 21 | |
| 22 | #include <sys/types.h> |
| 23 | #include <sys/stat.h> |
| 24 | #include <dirent.h> |
| 25 | #include <unistd.h> |
| 26 | |
| 27 | #include <string.h> |
| 28 | #include <cutils/atomic.h> |
Andreas Huber | 065c05e | 2010-01-04 15:02:02 -0800 | [diff] [blame] | 29 | #include <cutils/properties.h> |
Mathias Agopian | 6b3359d | 2010-01-29 17:16:30 -0800 | [diff] [blame] | 30 | #include <binder/MemoryBase.h> |
| 31 | #include <binder/MemoryHeapBase.h> |
Mathias Agopian | 7562408 | 2009-05-19 19:08:10 -0700 | [diff] [blame] | 32 | #include <binder/IPCThreadState.h> |
| 33 | #include <binder/IServiceManager.h> |
Dongwon Kang | d91dc5a | 2017-10-10 00:07:09 -0700 | [diff] [blame] | 34 | #include <media/DataSource.h> |
Andreas Huber | 1b86fe0 | 2014-01-29 11:13:26 -0800 | [diff] [blame] | 35 | #include <media/IMediaHTTPService.h> |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 36 | #include <media/MediaMetadataRetrieverInterface.h> |
| 37 | #include <media/MediaPlayerInterface.h> |
Dongwon Kang | d91dc5a | 2017-10-10 00:07:09 -0700 | [diff] [blame] | 38 | #include <media/stagefright/InterfaceUtils.h> |
Marco Nelissen | 83b0fd9 | 2015-09-16 13:48:07 -0700 | [diff] [blame] | 39 | #include <media/stagefright/Utils.h> |
Marco Nelissen | fa8be7d | 2019-09-23 12:15:57 -0700 | [diff] [blame] | 40 | #include <media/stagefright/FoundationUtils.h> |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 41 | #include <private/media/VideoFrame.h> |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 42 | #include "MetadataRetrieverClient.h" |
Andreas Huber | 2a4a7d5 | 2009-10-06 16:20:44 -0700 | [diff] [blame] | 43 | #include "StagefrightMetadataRetriever.h" |
John Grossman | 44a7e42 | 2012-06-21 17:29:24 -0700 | [diff] [blame] | 44 | #include "MediaPlayerFactory.h" |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 45 | |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 46 | namespace android { |
| 47 | |
| 48 | MetadataRetrieverClient::MetadataRetrieverClient(pid_t pid) |
| 49 | { |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 50 | ALOGV("MetadataRetrieverClient constructor pid(%d)", pid); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 51 | mPid = pid; |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 52 | mAlbumArt = NULL; |
Jean-Baptiste Queru | 6c5b210 | 2009-03-21 11:40:18 -0700 | [diff] [blame] | 53 | mRetriever = NULL; |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | MetadataRetrieverClient::~MetadataRetrieverClient() |
| 57 | { |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 58 | ALOGV("MetadataRetrieverClient destructor"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 59 | disconnect(); |
| 60 | } |
| 61 | |
Lajos Molnar | 6d339f1 | 2015-04-17 16:15:53 -0700 | [diff] [blame] | 62 | status_t MetadataRetrieverClient::dump(int fd, const Vector<String16>& /*args*/) |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 63 | { |
| 64 | const size_t SIZE = 256; |
| 65 | char buffer[SIZE]; |
| 66 | String8 result; |
| 67 | result.append(" MetadataRetrieverClient\n"); |
James Dong | 7f7d52a | 2011-01-06 12:20:35 -0800 | [diff] [blame] | 68 | snprintf(buffer, 255, " pid(%d)\n", mPid); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 69 | result.append(buffer); |
| 70 | write(fd, result.string(), result.size()); |
| 71 | write(fd, "\n", 1); |
| 72 | return NO_ERROR; |
| 73 | } |
| 74 | |
| 75 | void MetadataRetrieverClient::disconnect() |
| 76 | { |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 77 | ALOGV("disconnect from pid %d", mPid); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 78 | Mutex::Autolock lock(mLock); |
| 79 | mRetriever.clear(); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 80 | mAlbumArt.clear(); |
| 81 | IPCThreadState::self()->flushCommands(); |
| 82 | } |
| 83 | |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 84 | static sp<MediaMetadataRetrieverBase> createRetriever(player_type playerType) |
| 85 | { |
| 86 | sp<MediaMetadataRetrieverBase> p; |
| 87 | switch (playerType) { |
Andreas Huber | 47945ea | 2009-12-17 13:31:13 -0800 | [diff] [blame] | 88 | case STAGEFRIGHT_PLAYER: |
Andreas Huber | afed0e1 | 2011-09-20 15:39:58 -0700 | [diff] [blame] | 89 | case NU_PLAYER: |
Andreas Huber | 065c05e | 2010-01-04 15:02:02 -0800 | [diff] [blame] | 90 | { |
Andreas Huber | 608d77b | 2010-06-23 16:40:57 -0700 | [diff] [blame] | 91 | p = new StagefrightMetadataRetriever; |
| 92 | break; |
Andreas Huber | 065c05e | 2010-01-04 15:02:02 -0800 | [diff] [blame] | 93 | } |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 94 | default: |
| 95 | // TODO: |
Andreas Huber | 2a4a7d5 | 2009-10-06 16:20:44 -0700 | [diff] [blame] | 96 | // support for TEST_PLAYER |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 97 | ALOGE("player type %d is not supported", playerType); |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 98 | break; |
| 99 | } |
| 100 | if (p == NULL) { |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 101 | ALOGE("failed to create a retriever object"); |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 102 | } |
| 103 | return p; |
| 104 | } |
| 105 | |
Andreas Huber | af8791e | 2011-03-21 10:25:44 -0700 | [diff] [blame] | 106 | status_t MetadataRetrieverClient::setDataSource( |
Andreas Huber | 1b86fe0 | 2014-01-29 11:13:26 -0800 | [diff] [blame] | 107 | const sp<IMediaHTTPService> &httpService, |
| 108 | const char *url, |
| 109 | const KeyedVector<String8, String8> *headers) |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 110 | { |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 111 | ALOGV("setDataSource(%s)", url); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 112 | Mutex::Autolock lock(mLock); |
| 113 | if (url == NULL) { |
| 114 | return UNKNOWN_ERROR; |
| 115 | } |
John Grossman | 44a7e42 | 2012-06-21 17:29:24 -0700 | [diff] [blame] | 116 | |
| 117 | // When asking the MediaPlayerFactory subsystem to choose a media player for |
| 118 | // a given URL, a pointer to an outer IMediaPlayer can be passed to the |
| 119 | // factory system to be taken into consideration along with the URL. In the |
| 120 | // case of choosing an instance of a MediaPlayerBase for a |
| 121 | // MetadataRetrieverClient, there is no outer IMediaPlayer which will |
| 122 | // eventually encapsulate the result of this selection. In this case, just |
| 123 | // pass NULL to getPlayerType to indicate that there is no outer |
| 124 | // IMediaPlayer to consider during selection. |
| 125 | player_type playerType = |
| 126 | MediaPlayerFactory::getPlayerType(NULL /* client */, url); |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 127 | ALOGV("player type = %d", playerType); |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 128 | sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); |
| 129 | if (p == NULL) return NO_INIT; |
Andreas Huber | 1b86fe0 | 2014-01-29 11:13:26 -0800 | [diff] [blame] | 130 | status_t ret = p->setDataSource(httpService, url, headers); |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 131 | if (ret == NO_ERROR) mRetriever = p; |
| 132 | return ret; |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 133 | } |
| 134 | |
| 135 | status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t length) |
| 136 | { |
Marco Nelissen | 83b0fd9 | 2015-09-16 13:48:07 -0700 | [diff] [blame] | 137 | ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld", |
| 138 | fd, nameForFd(fd).c_str(), (long long) offset, (long long) length); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 139 | Mutex::Autolock lock(mLock); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 140 | struct stat sb; |
| 141 | int ret = fstat(fd, &sb); |
| 142 | if (ret != 0) { |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 143 | ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno)); |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 144 | return BAD_VALUE; |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 145 | } |
Andy Hung | 833b475 | 2016-04-04 17:15:48 -0700 | [diff] [blame] | 146 | ALOGV("st_dev = %llu", static_cast<unsigned long long>(sb.st_dev)); |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 147 | ALOGV("st_mode = %u", sb.st_mode); |
Mark Salyzyn | 77342f7 | 2014-06-18 16:31:32 -0700 | [diff] [blame] | 148 | ALOGV("st_uid = %lu", static_cast<unsigned long>(sb.st_uid)); |
| 149 | ALOGV("st_gid = %lu", static_cast<unsigned long>(sb.st_gid)); |
Andy Hung | 833b475 | 2016-04-04 17:15:48 -0700 | [diff] [blame] | 150 | ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size)); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 151 | |
| 152 | if (offset >= sb.st_size) { |
Andy Hung | 833b475 | 2016-04-04 17:15:48 -0700 | [diff] [blame] | 153 | ALOGE("offset (%lld) bigger than file size (%llu)", |
| 154 | (long long)offset, (unsigned long long)sb.st_size); |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 155 | return BAD_VALUE; |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 156 | } |
| 157 | if (offset + length > sb.st_size) { |
| 158 | length = sb.st_size - offset; |
Andy Hung | 833b475 | 2016-04-04 17:15:48 -0700 | [diff] [blame] | 159 | ALOGV("calculated length = %lld", (long long)length); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 160 | } |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 161 | |
John Grossman | 44a7e42 | 2012-06-21 17:29:24 -0700 | [diff] [blame] | 162 | player_type playerType = |
| 163 | MediaPlayerFactory::getPlayerType(NULL /* client */, |
| 164 | fd, |
| 165 | offset, |
| 166 | length); |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 167 | ALOGV("player type = %d", playerType); |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 168 | sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); |
| 169 | if (p == NULL) { |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 170 | return NO_INIT; |
| 171 | } |
James Dong | 7f7d52a | 2011-01-06 12:20:35 -0800 | [diff] [blame] | 172 | status_t status = p->setDataSource(fd, offset, length); |
James Dong | 148c1a2 | 2009-09-06 14:29:45 -0700 | [diff] [blame] | 173 | if (status == NO_ERROR) mRetriever = p; |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 174 | return status; |
| 175 | } |
| 176 | |
Chris Watkins | 99f3160 | 2015-03-20 13:06:33 -0700 | [diff] [blame] | 177 | status_t MetadataRetrieverClient::setDataSource( |
Chong Zhang | 24c1577 | 2017-07-26 16:25:28 -0700 | [diff] [blame] | 178 | const sp<IDataSource>& source, const char *mime) |
Chris Watkins | 99f3160 | 2015-03-20 13:06:33 -0700 | [diff] [blame] | 179 | { |
| 180 | ALOGV("setDataSource(IDataSource)"); |
| 181 | Mutex::Autolock lock(mLock); |
| 182 | |
Dongwon Kang | d91dc5a | 2017-10-10 00:07:09 -0700 | [diff] [blame] | 183 | sp<DataSource> dataSource = CreateDataSourceFromIDataSource(source); |
Chris Watkins | 99f3160 | 2015-03-20 13:06:33 -0700 | [diff] [blame] | 184 | player_type playerType = |
| 185 | MediaPlayerFactory::getPlayerType(NULL /* client */, dataSource); |
| 186 | ALOGV("player type = %d", playerType); |
| 187 | sp<MediaMetadataRetrieverBase> p = createRetriever(playerType); |
| 188 | if (p == NULL) return NO_INIT; |
Chong Zhang | 24c1577 | 2017-07-26 16:25:28 -0700 | [diff] [blame] | 189 | status_t ret = p->setDataSource(dataSource, mime); |
Chris Watkins | 99f3160 | 2015-03-20 13:06:33 -0700 | [diff] [blame] | 190 | if (ret == NO_ERROR) mRetriever = p; |
| 191 | return ret; |
| 192 | } |
| 193 | |
Marco Nelissen | 6155085 | 2015-06-12 15:31:23 -0700 | [diff] [blame] | 194 | Mutex MetadataRetrieverClient::sLock; |
| 195 | |
Chong Zhang | 24c1577 | 2017-07-26 16:25:28 -0700 | [diff] [blame] | 196 | sp<IMemory> MetadataRetrieverClient::getFrameAtTime( |
| 197 | int64_t timeUs, int option, int colorFormat, bool metaOnly) |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 198 | { |
Chong Zhang | 24c1577 | 2017-07-26 16:25:28 -0700 | [diff] [blame] | 199 | ALOGV("getFrameAtTime: time(%lld us) option(%d) colorFormat(%d), metaOnly(%d)", |
| 200 | (long long)timeUs, option, colorFormat, metaOnly); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 201 | Mutex::Autolock lock(mLock); |
Marco Nelissen | 6155085 | 2015-06-12 15:31:23 -0700 | [diff] [blame] | 202 | Mutex::Autolock glock(sLock); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 203 | if (mRetriever == NULL) { |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 204 | ALOGE("retriever is not initialized"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 205 | return NULL; |
| 206 | } |
Chong Zhang | 3f4e6dd | 2018-04-24 16:12:57 -0700 | [diff] [blame] | 207 | sp<IMemory> frame = mRetriever->getFrameAtTime(timeUs, option, colorFormat, metaOnly); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 208 | if (frame == NULL) { |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 209 | ALOGE("failed to capture a video frame"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 210 | return NULL; |
| 211 | } |
Chong Zhang | 3f4e6dd | 2018-04-24 16:12:57 -0700 | [diff] [blame] | 212 | return frame; |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 213 | } |
| 214 | |
| 215 | sp<IMemory> MetadataRetrieverClient::getImageAtIndex( |
Chong Zhang | d5fa357 | 2018-04-09 19:03:10 -0700 | [diff] [blame] | 216 | int index, int colorFormat, bool metaOnly, bool thumbnail) { |
Chong Zhang | 0c1407f | 2018-05-02 17:09:05 -0700 | [diff] [blame] | 217 | ALOGV("getImageAtIndex: index(%d) colorFormat(%d), metaOnly(%d) thumbnail(%d)", |
Chong Zhang | d5fa357 | 2018-04-09 19:03:10 -0700 | [diff] [blame] | 218 | index, colorFormat, metaOnly, thumbnail); |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 219 | Mutex::Autolock lock(mLock); |
| 220 | Mutex::Autolock glock(sLock); |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 221 | if (mRetriever == NULL) { |
| 222 | ALOGE("retriever is not initialized"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 223 | return NULL; |
| 224 | } |
Chong Zhang | 3f4e6dd | 2018-04-24 16:12:57 -0700 | [diff] [blame] | 225 | sp<IMemory> frame = mRetriever->getImageAtIndex(index, colorFormat, metaOnly, thumbnail); |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 226 | if (frame == NULL) { |
| 227 | ALOGE("failed to extract image"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 228 | return NULL; |
| 229 | } |
Chong Zhang | 3f4e6dd | 2018-04-24 16:12:57 -0700 | [diff] [blame] | 230 | return frame; |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 231 | } |
| 232 | |
Chong Zhang | 0c1407f | 2018-05-02 17:09:05 -0700 | [diff] [blame] | 233 | sp<IMemory> MetadataRetrieverClient::getImageRectAtIndex( |
| 234 | int index, int colorFormat, int left, int top, int right, int bottom) { |
| 235 | ALOGV("getImageRectAtIndex: index(%d) colorFormat(%d), rect {%d, %d, %d, %d}", |
| 236 | index, colorFormat, left, top, right, bottom); |
| 237 | Mutex::Autolock lock(mLock); |
| 238 | Mutex::Autolock glock(sLock); |
| 239 | if (mRetriever == NULL) { |
| 240 | ALOGE("retriever is not initialized"); |
| 241 | return NULL; |
| 242 | } |
| 243 | sp<IMemory> frame = mRetriever->getImageRectAtIndex( |
| 244 | index, colorFormat, left, top, right, bottom); |
| 245 | if (frame == NULL) { |
| 246 | ALOGE("failed to extract image"); |
| 247 | return NULL; |
| 248 | } |
| 249 | return frame; |
| 250 | } |
| 251 | |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 252 | status_t MetadataRetrieverClient::getFrameAtIndex( |
| 253 | std::vector<sp<IMemory> > *frames, |
| 254 | int frameIndex, int numFrames, int colorFormat, bool metaOnly) { |
| 255 | ALOGV("getFrameAtIndex: frameIndex(%d), numFrames(%d), colorFormat(%d), metaOnly(%d)", |
| 256 | frameIndex, numFrames, colorFormat, metaOnly); |
| 257 | Mutex::Autolock lock(mLock); |
| 258 | Mutex::Autolock glock(sLock); |
| 259 | if (mRetriever == NULL) { |
| 260 | ALOGE("retriever is not initialized"); |
| 261 | return INVALID_OPERATION; |
| 262 | } |
| 263 | |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 264 | status_t err = mRetriever->getFrameAtIndex( |
Chong Zhang | 3f4e6dd | 2018-04-24 16:12:57 -0700 | [diff] [blame] | 265 | frames, frameIndex, numFrames, colorFormat, metaOnly); |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 266 | if (err != OK) { |
Chong Zhang | 3f4e6dd | 2018-04-24 16:12:57 -0700 | [diff] [blame] | 267 | frames->clear(); |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 268 | return err; |
| 269 | } |
Chong Zhang | d3e0d86 | 2017-10-03 13:17:13 -0700 | [diff] [blame] | 270 | return OK; |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 271 | } |
| 272 | |
| 273 | sp<IMemory> MetadataRetrieverClient::extractAlbumArt() |
| 274 | { |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 275 | ALOGV("extractAlbumArt"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 276 | Mutex::Autolock lock(mLock); |
| 277 | mAlbumArt.clear(); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 278 | if (mRetriever == NULL) { |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 279 | ALOGE("retriever is not initialized"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 280 | return NULL; |
| 281 | } |
| 282 | MediaAlbumArt *albumArt = mRetriever->extractAlbumArt(); |
| 283 | if (albumArt == NULL) { |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 284 | ALOGE("failed to extract an album art"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 285 | return NULL; |
| 286 | } |
Elliott Hughes | f3e80dd | 2014-06-10 16:55:38 -0700 | [diff] [blame] | 287 | size_t size = sizeof(MediaAlbumArt) + albumArt->size(); |
Mathias Agopian | 6b3359d | 2010-01-29 17:16:30 -0800 | [diff] [blame] | 288 | sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "MetadataRetrieverClient"); |
| 289 | if (heap == NULL) { |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 290 | ALOGE("failed to create MemoryDealer object"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 291 | delete albumArt; |
| 292 | return NULL; |
| 293 | } |
Mathias Agopian | 6b3359d | 2010-01-29 17:16:30 -0800 | [diff] [blame] | 294 | mAlbumArt = new MemoryBase(heap, 0, size); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 295 | if (mAlbumArt == NULL) { |
Andy Hung | 833b475 | 2016-04-04 17:15:48 -0700 | [diff] [blame] | 296 | ALOGE("not enough memory for MediaAlbumArt size=%zu", size); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 297 | delete albumArt; |
| 298 | return NULL; |
| 299 | } |
Elliott Hughes | f3e80dd | 2014-06-10 16:55:38 -0700 | [diff] [blame] | 300 | MediaAlbumArt::init((MediaAlbumArt *) mAlbumArt->pointer(), |
| 301 | albumArt->size(), albumArt->data()); |
| 302 | delete albumArt; // We've taken our copy. |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 303 | return mAlbumArt; |
| 304 | } |
| 305 | |
| 306 | const char* MetadataRetrieverClient::extractMetadata(int keyCode) |
| 307 | { |
Steve Block | 3856b09 | 2011-10-20 11:56:00 +0100 | [diff] [blame] | 308 | ALOGV("extractMetadata"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 309 | Mutex::Autolock lock(mLock); |
| 310 | if (mRetriever == NULL) { |
Steve Block | 29357bc | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 311 | ALOGE("retriever is not initialized"); |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 312 | return NULL; |
| 313 | } |
| 314 | return mRetriever->extractMetadata(keyCode); |
| 315 | } |
| 316 | |
The Android Open Source Project | 7b5eb02 | 2008-12-17 18:05:43 -0800 | [diff] [blame] | 317 | }; // namespace android |