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
32using namespace android;
33
34const int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds
35const int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds
36
37//static
38sp<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
95SimpleDecodingSource::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
107SimpleDecodingSource::~SimpleDecodingSource() {
108    mCodec->release();
109    mLooper->stop();
110}
111
112status_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
134status_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
159sp<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
169SimpleDecodingSource::ProtectedState::ProtectedState(const sp<AMessage> &format)
170    : mReading(false),
171      mFormat(format),
172      mState(INIT),
173      mQueuedInputEOS(false),
174      mGotOutputEOS(false) {
175}
176
177status_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
198status_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