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