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