content/media/omx/OMXCodecProxy.cpp

branch
TOR_BUG_9701
changeset 13
44a2da4a2ab2
equal deleted inserted replaced
-1:000000000000 0:a042c0c44748
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 //#define LOG_NDEBUG 0
8 #define LOG_TAG "OMXCodecProxy"
9
10 #include <binder/IPCThreadState.h>
11 #include <cutils/properties.h>
12 #include <stagefright/foundation/ADebug.h>
13 #include <stagefright/MetaData.h>
14 #include <stagefright/OMXCodec.h>
15 #include <utils/Log.h>
16
17 #include "nsDebug.h"
18
19 #include "IMediaResourceManagerService.h"
20
21 #include "OMXCodecProxy.h"
22
23 namespace android {
24
25 // static
26 sp<OMXCodecProxy> OMXCodecProxy::Create(
27 const sp<IOMX> &omx,
28 const sp<MetaData> &meta, bool createEncoder,
29 const sp<MediaSource> &source,
30 const char *matchComponentName,
31 uint32_t flags,
32 const sp<ANativeWindow> &nativeWindow)
33 {
34 sp<OMXCodecProxy> proxy;
35
36 const char *mime;
37 if (!meta->findCString(kKeyMIMEType, &mime)) {
38 return nullptr;
39 }
40
41 if (!strncasecmp(mime, "video/", 6)) {
42 proxy = new OMXCodecProxy(omx, meta, createEncoder, source, matchComponentName, flags, nativeWindow);
43 }
44 return proxy;
45 }
46
47
48 OMXCodecProxy::OMXCodecProxy(
49 const sp<IOMX> &omx,
50 const sp<MetaData> &meta,
51 bool createEncoder,
52 const sp<MediaSource> &source,
53 const char *matchComponentName,
54 uint32_t flags,
55 const sp<ANativeWindow> &nativeWindow)
56 : mOMX(omx),
57 mSrcMeta(meta),
58 mIsEncoder(createEncoder),
59 mSource(source),
60 mComponentName(nullptr),
61 mFlags(flags),
62 mNativeWindow(nativeWindow),
63 mState(MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE)
64 {
65 }
66
67 OMXCodecProxy::~OMXCodecProxy()
68 {
69 mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
70
71 if (mOMXCodec.get()) {
72 wp<MediaSource> tmp = mOMXCodec;
73 mOMXCodec.clear();
74 while (tmp.promote() != nullptr) {
75 // this value come from stagefrigh's AwesomePlayer.
76 usleep(1000);
77 }
78 }
79 // Complete all pending Binder ipc transactions
80 IPCThreadState::self()->flushCommands();
81
82 if (mManagerService.get() && mClient.get()) {
83 mManagerService->cancelClient(mClient);
84 }
85
86 mSource.clear();
87 free(mComponentName);
88 mComponentName = nullptr;
89 }
90
91 MediaResourceManagerClient::State OMXCodecProxy::getState()
92 {
93 Mutex::Autolock autoLock(mLock);
94 return mState;
95 }
96
97 void OMXCodecProxy::setEventListener(const wp<OMXCodecProxy::EventListener>& listener)
98 {
99 Mutex::Autolock autoLock(mLock);
100 mEventListener = listener;
101 }
102
103 void OMXCodecProxy::notifyStatusChangedLocked()
104 {
105 if (mEventListener != nullptr) {
106 sp<EventListener> listener = mEventListener.promote();
107 if (listener != nullptr) {
108 listener->statusChanged();
109 }
110 }
111 }
112
113 void OMXCodecProxy::requestResource()
114 {
115 Mutex::Autolock autoLock(mLock);
116
117 if (mClient.get()) {
118 return;
119 }
120 sp<MediaResourceManagerClient::EventListener> listener = this;
121 mClient = new MediaResourceManagerClient(listener);
122
123 mManagerService = mClient->getMediaResourceManagerService();
124 if (!mManagerService.get()) {
125 mClient = nullptr;
126 return;
127 }
128
129 mManagerService->requestMediaResource(mClient, MediaResourceManagerClient::HW_VIDEO_DECODER);
130 }
131
132 bool OMXCodecProxy::IsWaitingResources()
133 {
134 Mutex::Autolock autoLock(mLock);
135 return mState == MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE;
136 }
137
138 // called on Binder ipc thread
139 void OMXCodecProxy::statusChanged(int event)
140 {
141 Mutex::Autolock autoLock(mLock);
142
143 if (mState != MediaResourceManagerClient::CLIENT_STATE_WAIT_FOR_RESOURCE) {
144 return;
145 }
146
147 mState = (MediaResourceManagerClient::State) event;
148 if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
149 return;
150 }
151
152 const char *mime;
153 if (!mSrcMeta->findCString(kKeyMIMEType, &mime)) {
154 mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
155 notifyStatusChangedLocked();
156 return;
157 }
158
159 if (!strncasecmp(mime, "video/", 6)) {
160 sp<MediaSource> codec;
161 mOMXCodec = OMXCodec::Create(mOMX, mSrcMeta, mIsEncoder, mSource, mComponentName, mFlags, mNativeWindow);
162 if (mOMXCodec == nullptr) {
163 mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
164 notifyStatusChangedLocked();
165 return;
166 }
167 // Check if this video is sized such that we're comfortable
168 // possibly using an OMX decoder.
169 int32_t maxWidth, maxHeight;
170 char propValue[PROPERTY_VALUE_MAX];
171 property_get("ro.moz.omx.hw.max_width", propValue, "-1");
172 maxWidth = atoi(propValue);
173 property_get("ro.moz.omx.hw.max_height", propValue, "-1");
174 maxHeight = atoi(propValue);
175
176 int32_t width = -1, height = -1;
177 if (maxWidth > 0 && maxHeight > 0 &&
178 !(mOMXCodec->getFormat()->findInt32(kKeyWidth, &width) &&
179 mOMXCodec->getFormat()->findInt32(kKeyHeight, &height) &&
180 width * height <= maxWidth * maxHeight)) {
181 printf_stderr("Failed to get video size, or it was too large for HW decoder (<w=%d, h=%d> but <maxW=%d, maxH=%d>)",
182 width, height, maxWidth, maxHeight);
183 mOMXCodec.clear();
184 mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
185 notifyStatusChangedLocked();
186 return;
187 }
188
189 if (mOMXCodec->start() != OK) {
190 NS_WARNING("Couldn't start OMX video source");
191 mOMXCodec.clear();
192 mState = MediaResourceManagerClient::CLIENT_STATE_SHUTDOWN;
193 notifyStatusChangedLocked();
194 return;
195 }
196 }
197 notifyStatusChangedLocked();
198 }
199
200 status_t OMXCodecProxy::start(MetaData *params)
201 {
202 Mutex::Autolock autoLock(mLock);
203
204 if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
205 return NO_INIT;
206 }
207 CHECK(mOMXCodec.get() != nullptr);
208 return mOMXCodec->start();
209 }
210
211 status_t OMXCodecProxy::stop()
212 {
213 Mutex::Autolock autoLock(mLock);
214
215 if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
216 return NO_INIT;
217 }
218 CHECK(mOMXCodec.get() != nullptr);
219 return mOMXCodec->stop();
220 }
221
222 sp<MetaData> OMXCodecProxy::getFormat()
223 {
224 Mutex::Autolock autoLock(mLock);
225
226 if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
227 sp<MetaData> meta = new MetaData;
228 return meta;
229 }
230 CHECK(mOMXCodec.get() != nullptr);
231 return mOMXCodec->getFormat();
232 }
233
234 status_t OMXCodecProxy::read(MediaBuffer **buffer, const ReadOptions *options)
235 {
236 Mutex::Autolock autoLock(mLock);
237
238 if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
239 return NO_INIT;
240 }
241 CHECK(mOMXCodec.get() != nullptr);
242 return mOMXCodec->read(buffer, options);
243 }
244
245 status_t OMXCodecProxy::pause()
246 {
247 Mutex::Autolock autoLock(mLock);
248
249 if (mState != MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED) {
250 return NO_INIT;
251 }
252 CHECK(mOMXCodec.get() != nullptr);
253 return mOMXCodec->pause();
254 }
255
256 } // namespace android

mercurial