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, &timestampUs));
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