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