1 /*
2 * Copyright 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gui/Surface.h>
18
19 #include <media/ICrypto.h>
20 #include <media/stagefright/foundation/ABuffer.h>
21 #include <media/stagefright/foundation/ALooper.h>
22 #include <media/stagefright/foundation/AMessage.h>
23 #include <media/stagefright/foundation/AUtils.h>
24 #include <media/stagefright/MediaBuffer.h>
25 #include <media/stagefright/MediaCodecList.h>
26 #include <media/stagefright/MediaCodec.h>
27 #include <media/stagefright/MetaData.h>
28 #include <media/stagefright/SimpleDecodingSource.h>
29 #include <media/stagefright/Utils.h>
30
31 using namespace android;
32
33 const int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds
34 const int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds
35
36 //static
Create(const sp<IMediaSource> & source,uint32_t flags,const sp<ANativeWindow> & nativeWindow,const char * desiredCodec)37 sp<SimpleDecodingSource> SimpleDecodingSource::Create(
38 const sp<IMediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow,
39 const char *desiredCodec) {
40 sp<Surface> surface = static_cast<Surface*>(nativeWindow.get());
41 const char *mime = NULL;
42 sp<MetaData> meta = source->getFormat();
43 CHECK(meta->findCString(kKeyMIMEType, &mime));
44
45 sp<AMessage> format = new AMessage;
46 convertMetaDataToMessage(source->getFormat(), &format);
47
48 Vector<AString> matchingCodecs;
49 MediaCodecList::findMatchingCodecs(
50 mime, false /* encoder */, flags, &matchingCodecs);
51
52 sp<ALooper> looper = new ALooper;
53 looper->setName("stagefright");
54 looper->start();
55
56 sp<MediaCodec> codec;
57
58 for (size_t i = 0; i < matchingCodecs.size(); ++i) {
59 const AString &componentName = matchingCodecs[i];
60 if (desiredCodec != NULL && componentName.compare(desiredCodec)) {
61 continue;
62 }
63
64 ALOGV("Attempting to allocate codec '%s'", componentName.c_str());
65
66 codec = MediaCodec::CreateByComponentName(looper, componentName);
67 if (codec != NULL) {
68 ALOGI("Successfully allocated codec '%s'", componentName.c_str());
69
70 status_t err = codec->configure(format, surface, NULL /* crypto */, 0 /* flags */);
71 if (err == OK) {
72 err = codec->getOutputFormat(&format);
73 }
74 if (err == OK) {
75 return new SimpleDecodingSource(codec, source, looper, surface != NULL, format);
76 }
77
78 ALOGD("Failed to configure codec '%s'", componentName.c_str());
79 codec->release();
80 codec = NULL;
81 }
82 }
83
84 looper->stop();
85 ALOGE("No matching decoder! (mime: %s)", mime);
86 return NULL;
87 }
88
SimpleDecodingSource(const sp<MediaCodec> & codec,const sp<IMediaSource> & source,const sp<ALooper> & looper,bool usingSurface,const sp<AMessage> & format)89 SimpleDecodingSource::SimpleDecodingSource(
90 const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper,
91 bool usingSurface, const sp<AMessage> &format)
92 : mCodec(codec),
93 mSource(source),
94 mLooper(looper),
95 mUsingSurface(usingSurface),
96 mProtectedState(format) {
97 mCodec->getName(&mComponentName);
98 }
99
~SimpleDecodingSource()100 SimpleDecodingSource::~SimpleDecodingSource() {
101 mCodec->release();
102 mLooper->stop();
103 }
104
start(MetaData * params)105 status_t SimpleDecodingSource::start(MetaData *params) {
106 (void)params;
107 Mutexed<ProtectedState>::Locked me(mProtectedState);
108 if (me->mState != INIT) {
109 return -EINVAL;
110 }
111 status_t res = mCodec->start();
112 if (res == OK) {
113 res = mSource->start();
114 }
115
116 if (res == OK) {
117 me->mState = STARTED;
118 me->mQueuedInputEOS = false;
119 me->mGotOutputEOS = false;
120 } else {
121 me->mState = ERROR;
122 }
123
124 return res;
125 }
126
stop()127 status_t SimpleDecodingSource::stop() {
128 Mutexed<ProtectedState>::Locked me(mProtectedState);
129 if (me->mState != STARTED) {
130 return -EINVAL;
131 }
132
133 // wait for any pending reads to complete
134 me->mState = STOPPING;
135 while (me->mReading) {
136 me.waitForCondition(me->mReadCondition);
137 }
138
139 status_t res1 = mCodec->stop();
140 if (res1 != OK) {
141 mCodec->release();
142 }
143 status_t res2 = mSource->stop();
144 if (res1 == OK && res2 == OK) {
145 me->mState = STOPPED;
146 } else {
147 me->mState = ERROR;
148 }
149 return res1 != OK ? res1 : res2;
150 }
151
getFormat()152 sp<MetaData> SimpleDecodingSource::getFormat() {
153 Mutexed<ProtectedState>::Locked me(mProtectedState);
154 if (me->mState == STARTED || me->mState == INIT) {
155 sp<MetaData> meta = new MetaData();
156 convertMessageToMetaData(me->mFormat, meta);
157 return meta;
158 }
159 return NULL;
160 }
161
ProtectedState(const sp<AMessage> & format)162 SimpleDecodingSource::ProtectedState::ProtectedState(const sp<AMessage> &format)
163 : mReading(false),
164 mFormat(format),
165 mState(INIT),
166 mQueuedInputEOS(false),
167 mGotOutputEOS(false) {
168 }
169
read(MediaBuffer ** buffer,const ReadOptions * options)170 status_t SimpleDecodingSource::read(
171 MediaBuffer **buffer, const ReadOptions *options) {
172 *buffer = NULL;
173
174 Mutexed<ProtectedState>::Locked me(mProtectedState);
175 if (me->mState != STARTED) {
176 return ERROR_END_OF_STREAM;
177 }
178 me->mReading = true;
179
180 status_t res = doRead(me, buffer, options);
181
182 me.lock();
183 me->mReading = false;
184 if (me->mState != STARTED) {
185 me->mReadCondition.signal();
186 }
187
188 return res;
189 }
190
doRead(Mutexed<ProtectedState>::Locked & me,MediaBuffer ** buffer,const ReadOptions * options)191 status_t SimpleDecodingSource::doRead(
192 Mutexed<ProtectedState>::Locked &me, MediaBuffer **buffer, const ReadOptions *options) {
193 // |me| is always locked on entry, but is allowed to be unlocked on exit
194 CHECK_EQ(me->mState, STARTED);
195
196 size_t out_ix, in_ix, out_offset, out_size;
197 int64_t out_pts;
198 uint32_t out_flags;
199 status_t res;
200
201 // flush codec on seek
202 IMediaSource::ReadOptions::SeekMode mode;
203 if (options != NULL && options->getSeekTo(&out_pts, &mode)) {
204 me->mQueuedInputEOS = false;
205 me->mGotOutputEOS = false;
206 mCodec->flush();
207 }
208
209 if (me->mGotOutputEOS) {
210 return ERROR_END_OF_STREAM;
211 }
212
213 for (int retries = 0; ++retries; ) {
214 // If we fill all available input buffers, we should expect that
215 // the codec produces at least one output buffer. Also, the codec
216 // should produce an output buffer in at most 1 seconds. Retry a
217 // few times nonetheless.
218 while (!me->mQueuedInputEOS) {
219 // allow some time to get input buffer after flush
220 res = mCodec->dequeueInputBuffer(&in_ix, kTimeoutWaitForInputUs);
221 if (res == -EAGAIN) {
222 // no available input buffers
223 break;
224 }
225
226 sp<ABuffer> in_buffer;
227 if (res == OK) {
228 res = mCodec->getInputBuffer(in_ix, &in_buffer);
229 }
230
231 if (res != OK || in_buffer == NULL) {
232 ALOGW("[%s] could not get input buffer #%zu",
233 mComponentName.c_str(), in_ix);
234 me->mState = ERROR;
235 return UNKNOWN_ERROR;
236 }
237
238 MediaBuffer *in_buf;
239 while (true) {
240 in_buf = NULL;
241 me.unlock();
242 res = mSource->read(&in_buf, options);
243 me.lock();
244 if (res != OK || me->mState != STARTED) {
245 if (in_buf != NULL) {
246 in_buf->release();
247 in_buf = NULL;
248 }
249
250 // queue EOS
251 me->mQueuedInputEOS = true;
252 if (mCodec->queueInputBuffer(
253 in_ix, 0 /* offset */, 0 /* size */,
254 0 /* pts */, MediaCodec::BUFFER_FLAG_EOS) != OK) {
255 ALOGI("[%s] failed to queue input EOS", mComponentName.c_str());
256 me->mState = ERROR;
257 return UNKNOWN_ERROR;
258 }
259
260 // don't stop on EOS, but report error or EOS on stop
261 if (res != ERROR_END_OF_STREAM) {
262 me->mState = ERROR;
263 return res;
264 }
265 if (me->mState != STARTED) {
266 return ERROR_END_OF_STREAM;
267 }
268 break;
269 }
270 if (in_buf == NULL) { // should not happen
271 continue;
272 } else if (in_buf->range_length() != 0) {
273 break;
274 }
275 in_buf->release();
276 }
277
278 if (in_buf != NULL) {
279 int64_t timestampUs = 0;
280 CHECK(in_buf->meta_data()->findInt64(kKeyTime, ×tampUs));
281 if (in_buf->range_length() > in_buffer->capacity()) {
282 ALOGW("'%s' received %zu input bytes for buffer of size %zu",
283 mComponentName.c_str(),
284 in_buf->range_length(), in_buffer->capacity());
285 }
286 memcpy(in_buffer->base(), (uint8_t *)in_buf->data() + in_buf->range_offset(),
287 min(in_buf->range_length(), in_buffer->capacity()));
288
289 res = mCodec->queueInputBuffer(
290 in_ix, 0 /* offset */, in_buf->range_length(),
291 timestampUs, 0 /* flags */);
292 if (res != OK) {
293 ALOGI("[%s] failed to queue input buffer #%zu", mComponentName.c_str(), in_ix);
294 me->mState = ERROR;
295 }
296 in_buf->release();
297 }
298 }
299
300 me.unlock();
301 res = mCodec->dequeueOutputBuffer(
302 &out_ix, &out_offset, &out_size, &out_pts,
303 &out_flags, kTimeoutWaitForOutputUs /* timeoutUs */);
304 me.lock();
305 // abort read on stop
306 if (me->mState != STARTED) {
307 if (res == OK) {
308 mCodec->releaseOutputBuffer(out_ix);
309 }
310 return ERROR_END_OF_STREAM;
311 }
312
313 if (res == -EAGAIN) {
314 ALOGD("[%s] did not produce an output buffer. retry count: %d",
315 mComponentName.c_str(), retries);
316 continue;
317 } else if (res == INFO_FORMAT_CHANGED) {
318 if (mCodec->getOutputFormat(&me->mFormat) != OK) {
319 me->mState = ERROR;
320 res = UNKNOWN_ERROR;
321 }
322 return res;
323 } else if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
324 ALOGV("output buffers changed");
325 continue;
326 } else if (res != OK) {
327 me->mState = ERROR;
328 return res;
329 }
330
331 sp<ABuffer> out_buffer;
332 res = mCodec->getOutputBuffer(out_ix, &out_buffer);
333 if (res != OK) {
334 ALOGW("[%s] could not get output buffer #%zu",
335 mComponentName.c_str(), out_ix);
336 me->mState = ERROR;
337 return UNKNOWN_ERROR;
338 }
339 if (out_flags & MediaCodec::BUFFER_FLAG_EOS) {
340 me->mGotOutputEOS = true;
341 // return EOS immediately if last buffer is empty
342 if (out_size == 0) {
343 mCodec->releaseOutputBuffer(out_ix);
344 return ERROR_END_OF_STREAM;
345 }
346 }
347
348 if (mUsingSurface && out_size > 0) {
349 *buffer = new MediaBuffer(0);
350 mCodec->renderOutputBufferAndRelease(out_ix);
351 } else {
352 *buffer = new MediaBuffer(out_size);
353 CHECK_LE(out_buffer->size(), (*buffer)->size());
354 memcpy((*buffer)->data(), out_buffer->data(), out_buffer->size());
355 (*buffer)->meta_data()->setInt64(kKeyTime, out_pts);
356 mCodec->releaseOutputBuffer(out_ix);
357 }
358 return OK;
359 }
360
361 return TIMED_OUT;
362 }
363