1 /*
2  * Copyright 2012, 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 "MediaCodec"
19 #include <inttypes.h>
20 
21 #include "include/avc_utils.h"
22 #include "include/SoftwareRenderer.h"
23 
24 #include <binder/IBatteryStats.h>
25 #include <binder/IServiceManager.h>
26 #include <gui/Surface.h>
27 #include <media/ICrypto.h>
28 #include <media/stagefright/foundation/ABuffer.h>
29 #include <media/stagefright/foundation/ADebug.h>
30 #include <media/stagefright/foundation/AMessage.h>
31 #include <media/stagefright/foundation/AString.h>
32 #include <media/stagefright/foundation/hexdump.h>
33 #include <media/stagefright/ACodec.h>
34 #include <media/stagefright/BufferProducerWrapper.h>
35 #include <media/stagefright/MediaCodec.h>
36 #include <media/stagefright/MediaCodecList.h>
37 #include <media/stagefright/MediaDefs.h>
38 #include <media/stagefright/MediaErrors.h>
39 #include <media/stagefright/MetaData.h>
40 #include <media/stagefright/NativeWindowWrapper.h>
41 #include <private/android_filesystem_config.h>
42 #include <utils/Log.h>
43 #include <utils/Singleton.h>
44 
45 namespace android {
46 
47 struct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
48     BatteryNotifier();
49 
50     void noteStartVideo();
51     void noteStopVideo();
52     void noteStartAudio();
53     void noteStopAudio();
54 
55 private:
56     int32_t mVideoRefCount;
57     int32_t mAudioRefCount;
58     sp<IBatteryStats> mBatteryStatService;
59 };
60 
ANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)61 ANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
62 
63 MediaCodec::BatteryNotifier::BatteryNotifier() :
64     mVideoRefCount(0),
65     mAudioRefCount(0) {
66     // get battery service
67     const sp<IServiceManager> sm(defaultServiceManager());
68     if (sm != NULL) {
69         const String16 name("batterystats");
70         mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
71         if (mBatteryStatService == NULL) {
72             ALOGE("batterystats service unavailable!");
73         }
74     }
75 }
76 
noteStartVideo()77 void MediaCodec::BatteryNotifier::noteStartVideo() {
78     if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
79         mBatteryStatService->noteStartVideo(AID_MEDIA);
80     }
81     mVideoRefCount++;
82 }
83 
noteStopVideo()84 void MediaCodec::BatteryNotifier::noteStopVideo() {
85     if (mVideoRefCount == 0) {
86         ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
87         return;
88     }
89 
90     mVideoRefCount--;
91     if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
92         mBatteryStatService->noteStopVideo(AID_MEDIA);
93     }
94 }
95 
noteStartAudio()96 void MediaCodec::BatteryNotifier::noteStartAudio() {
97     if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
98         mBatteryStatService->noteStartAudio(AID_MEDIA);
99     }
100     mAudioRefCount++;
101 }
102 
noteStopAudio()103 void MediaCodec::BatteryNotifier::noteStopAudio() {
104     if (mAudioRefCount == 0) {
105         ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
106         return;
107     }
108 
109     mAudioRefCount--;
110     if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
111         mBatteryStatService->noteStopAudio(AID_MEDIA);
112     }
113 }
114 // static
CreateByType(const sp<ALooper> & looper,const char * mime,bool encoder,status_t * err)115 sp<MediaCodec> MediaCodec::CreateByType(
116         const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
117     sp<MediaCodec> codec = new MediaCodec(looper);
118 
119     const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
120     if (err != NULL) {
121         *err = ret;
122     }
123     return ret == OK ? codec : NULL; // NULL deallocates codec.
124 }
125 
126 // static
CreateByComponentName(const sp<ALooper> & looper,const char * name,status_t * err)127 sp<MediaCodec> MediaCodec::CreateByComponentName(
128         const sp<ALooper> &looper, const char *name, status_t *err) {
129     sp<MediaCodec> codec = new MediaCodec(looper);
130 
131     const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
132     if (err != NULL) {
133         *err = ret;
134     }
135     return ret == OK ? codec : NULL; // NULL deallocates codec.
136 }
137 
MediaCodec(const sp<ALooper> & looper)138 MediaCodec::MediaCodec(const sp<ALooper> &looper)
139     : mState(UNINITIALIZED),
140       mLooper(looper),
141       mCodec(NULL),
142       mReplyID(0),
143       mFlags(0),
144       mStickyError(OK),
145       mSoftRenderer(NULL),
146       mBatteryStatNotified(false),
147       mIsVideo(false),
148       mDequeueInputTimeoutGeneration(0),
149       mDequeueInputReplyID(0),
150       mDequeueOutputTimeoutGeneration(0),
151       mDequeueOutputReplyID(0),
152       mHaveInputSurface(false) {
153 }
154 
~MediaCodec()155 MediaCodec::~MediaCodec() {
156     CHECK_EQ(mState, UNINITIALIZED);
157 }
158 
159 // static
PostAndAwaitResponse(const sp<AMessage> & msg,sp<AMessage> * response)160 status_t MediaCodec::PostAndAwaitResponse(
161         const sp<AMessage> &msg, sp<AMessage> *response) {
162     status_t err = msg->postAndAwaitResponse(response);
163 
164     if (err != OK) {
165         return err;
166     }
167 
168     if (!(*response)->findInt32("err", &err)) {
169         err = OK;
170     }
171 
172     return err;
173 }
174 
175 // static
PostReplyWithError(int32_t replyID,int32_t err)176 void MediaCodec::PostReplyWithError(int32_t replyID, int32_t err) {
177     sp<AMessage> response = new AMessage;
178     response->setInt32("err", err);
179     response->postReply(replyID);
180 }
181 
init(const AString & name,bool nameIsType,bool encoder)182 status_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
183     // save init parameters for reset
184     mInitName = name;
185     mInitNameIsType = nameIsType;
186     mInitIsEncoder = encoder;
187 
188     // Current video decoders do not return from OMX_FillThisBuffer
189     // quickly, violating the OpenMAX specs, until that is remedied
190     // we need to invest in an extra looper to free the main event
191     // queue.
192     mCodec = new ACodec;
193     bool needDedicatedLooper = false;
194     if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
195         needDedicatedLooper = true;
196     } else {
197         AString tmp = name;
198         if (tmp.endsWith(".secure")) {
199             tmp.erase(tmp.size() - 7, 7);
200         }
201         const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
202         ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
203         if (codecIdx >= 0) {
204             const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
205             Vector<AString> mimes;
206             info->getSupportedMimes(&mimes);
207             for (size_t i = 0; i < mimes.size(); i++) {
208                 if (mimes[i].startsWith("video/")) {
209                     needDedicatedLooper = true;
210                     break;
211                 }
212             }
213         }
214     }
215 
216     if (needDedicatedLooper) {
217         if (mCodecLooper == NULL) {
218             mCodecLooper = new ALooper;
219             mCodecLooper->setName("CodecLooper");
220             mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
221         }
222 
223         mCodecLooper->registerHandler(mCodec);
224     } else {
225         mLooper->registerHandler(mCodec);
226     }
227 
228     mLooper->registerHandler(this);
229 
230     mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
231 
232     sp<AMessage> msg = new AMessage(kWhatInit, id());
233     msg->setString("name", name);
234     msg->setInt32("nameIsType", nameIsType);
235 
236     if (nameIsType) {
237         msg->setInt32("encoder", encoder);
238     }
239 
240     sp<AMessage> response;
241     return PostAndAwaitResponse(msg, &response);
242 }
243 
setCallback(const sp<AMessage> & callback)244 status_t MediaCodec::setCallback(const sp<AMessage> &callback) {
245     sp<AMessage> msg = new AMessage(kWhatSetCallback, id());
246     msg->setMessage("callback", callback);
247 
248     sp<AMessage> response;
249     return PostAndAwaitResponse(msg, &response);
250 }
251 
configure(const sp<AMessage> & format,const sp<Surface> & nativeWindow,const sp<ICrypto> & crypto,uint32_t flags)252 status_t MediaCodec::configure(
253         const sp<AMessage> &format,
254         const sp<Surface> &nativeWindow,
255         const sp<ICrypto> &crypto,
256         uint32_t flags) {
257     sp<AMessage> msg = new AMessage(kWhatConfigure, id());
258 
259     msg->setMessage("format", format);
260     msg->setInt32("flags", flags);
261 
262     if (nativeWindow != NULL) {
263         msg->setObject(
264                 "native-window",
265                 new NativeWindowWrapper(nativeWindow));
266     }
267 
268     if (crypto != NULL) {
269         msg->setPointer("crypto", crypto.get());
270     }
271 
272     sp<AMessage> response;
273     status_t err = PostAndAwaitResponse(msg, &response);
274 
275     if (err != OK && err != INVALID_OPERATION) {
276         // MediaCodec now set state to UNINITIALIZED upon any fatal error.
277         // To maintain backward-compatibility, do a reset() to put codec
278         // back into INITIALIZED state.
279         // But don't reset if the err is INVALID_OPERATION, which means
280         // the configure failure is due to wrong state.
281 
282         ALOGE("configure failed with err 0x%08x, resetting...", err);
283         reset();
284     }
285 
286     return err;
287 }
288 
createInputSurface(sp<IGraphicBufferProducer> * bufferProducer)289 status_t MediaCodec::createInputSurface(
290         sp<IGraphicBufferProducer>* bufferProducer) {
291     sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
292 
293     sp<AMessage> response;
294     status_t err = PostAndAwaitResponse(msg, &response);
295     if (err == NO_ERROR) {
296         // unwrap the sp<IGraphicBufferProducer>
297         sp<RefBase> obj;
298         bool found = response->findObject("input-surface", &obj);
299         CHECK(found);
300         sp<BufferProducerWrapper> wrapper(
301                 static_cast<BufferProducerWrapper*>(obj.get()));
302         *bufferProducer = wrapper->getBufferProducer();
303     } else {
304         ALOGW("createInputSurface failed, err=%d", err);
305     }
306     return err;
307 }
308 
start()309 status_t MediaCodec::start() {
310     sp<AMessage> msg = new AMessage(kWhatStart, id());
311 
312     sp<AMessage> response;
313     return PostAndAwaitResponse(msg, &response);
314 }
315 
stop()316 status_t MediaCodec::stop() {
317     sp<AMessage> msg = new AMessage(kWhatStop, id());
318 
319     sp<AMessage> response;
320     return PostAndAwaitResponse(msg, &response);
321 }
322 
release()323 status_t MediaCodec::release() {
324     sp<AMessage> msg = new AMessage(kWhatRelease, id());
325 
326     sp<AMessage> response;
327     return PostAndAwaitResponse(msg, &response);
328 }
329 
reset()330 status_t MediaCodec::reset() {
331     /* When external-facing MediaCodec object is created,
332        it is already initialized.  Thus, reset is essentially
333        release() followed by init(), plus clearing the state */
334 
335     status_t err = release();
336 
337     // unregister handlers
338     if (mCodec != NULL) {
339         if (mCodecLooper != NULL) {
340             mCodecLooper->unregisterHandler(mCodec->id());
341         } else {
342             mLooper->unregisterHandler(mCodec->id());
343         }
344         mCodec = NULL;
345     }
346     mLooper->unregisterHandler(id());
347 
348     mFlags = 0;    // clear all flags
349     mStickyError = OK;
350 
351     // reset state not reset by setState(UNINITIALIZED)
352     mReplyID = 0;
353     mDequeueInputReplyID = 0;
354     mDequeueOutputReplyID = 0;
355     mDequeueInputTimeoutGeneration = 0;
356     mDequeueOutputTimeoutGeneration = 0;
357     mHaveInputSurface = false;
358 
359     if (err == OK) {
360         err = init(mInitName, mInitNameIsType, mInitIsEncoder);
361     }
362     return err;
363 }
364 
queueInputBuffer(size_t index,size_t offset,size_t size,int64_t presentationTimeUs,uint32_t flags,AString * errorDetailMsg)365 status_t MediaCodec::queueInputBuffer(
366         size_t index,
367         size_t offset,
368         size_t size,
369         int64_t presentationTimeUs,
370         uint32_t flags,
371         AString *errorDetailMsg) {
372     if (errorDetailMsg != NULL) {
373         errorDetailMsg->clear();
374     }
375 
376     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
377     msg->setSize("index", index);
378     msg->setSize("offset", offset);
379     msg->setSize("size", size);
380     msg->setInt64("timeUs", presentationTimeUs);
381     msg->setInt32("flags", flags);
382     msg->setPointer("errorDetailMsg", errorDetailMsg);
383 
384     sp<AMessage> response;
385     return PostAndAwaitResponse(msg, &response);
386 }
387 
queueSecureInputBuffer(size_t index,size_t offset,const CryptoPlugin::SubSample * subSamples,size_t numSubSamples,const uint8_t key[16],const uint8_t iv[16],CryptoPlugin::Mode mode,int64_t presentationTimeUs,uint32_t flags,AString * errorDetailMsg)388 status_t MediaCodec::queueSecureInputBuffer(
389         size_t index,
390         size_t offset,
391         const CryptoPlugin::SubSample *subSamples,
392         size_t numSubSamples,
393         const uint8_t key[16],
394         const uint8_t iv[16],
395         CryptoPlugin::Mode mode,
396         int64_t presentationTimeUs,
397         uint32_t flags,
398         AString *errorDetailMsg) {
399     if (errorDetailMsg != NULL) {
400         errorDetailMsg->clear();
401     }
402 
403     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
404     msg->setSize("index", index);
405     msg->setSize("offset", offset);
406     msg->setPointer("subSamples", (void *)subSamples);
407     msg->setSize("numSubSamples", numSubSamples);
408     msg->setPointer("key", (void *)key);
409     msg->setPointer("iv", (void *)iv);
410     msg->setInt32("mode", mode);
411     msg->setInt64("timeUs", presentationTimeUs);
412     msg->setInt32("flags", flags);
413     msg->setPointer("errorDetailMsg", errorDetailMsg);
414 
415     sp<AMessage> response;
416     status_t err = PostAndAwaitResponse(msg, &response);
417 
418     return err;
419 }
420 
dequeueInputBuffer(size_t * index,int64_t timeoutUs)421 status_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
422     sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
423     msg->setInt64("timeoutUs", timeoutUs);
424 
425     sp<AMessage> response;
426     status_t err;
427     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
428         return err;
429     }
430 
431     CHECK(response->findSize("index", index));
432 
433     return OK;
434 }
435 
dequeueOutputBuffer(size_t * index,size_t * offset,size_t * size,int64_t * presentationTimeUs,uint32_t * flags,int64_t timeoutUs)436 status_t MediaCodec::dequeueOutputBuffer(
437         size_t *index,
438         size_t *offset,
439         size_t *size,
440         int64_t *presentationTimeUs,
441         uint32_t *flags,
442         int64_t timeoutUs) {
443     sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
444     msg->setInt64("timeoutUs", timeoutUs);
445 
446     sp<AMessage> response;
447     status_t err;
448     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
449         return err;
450     }
451 
452     CHECK(response->findSize("index", index));
453     CHECK(response->findSize("offset", offset));
454     CHECK(response->findSize("size", size));
455     CHECK(response->findInt64("timeUs", presentationTimeUs));
456     CHECK(response->findInt32("flags", (int32_t *)flags));
457 
458     return OK;
459 }
460 
renderOutputBufferAndRelease(size_t index)461 status_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
462     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
463     msg->setSize("index", index);
464     msg->setInt32("render", true);
465 
466     sp<AMessage> response;
467     return PostAndAwaitResponse(msg, &response);
468 }
469 
renderOutputBufferAndRelease(size_t index,int64_t timestampNs)470 status_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
471     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
472     msg->setSize("index", index);
473     msg->setInt32("render", true);
474     msg->setInt64("timestampNs", timestampNs);
475 
476     sp<AMessage> response;
477     return PostAndAwaitResponse(msg, &response);
478 }
479 
releaseOutputBuffer(size_t index)480 status_t MediaCodec::releaseOutputBuffer(size_t index) {
481     sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
482     msg->setSize("index", index);
483 
484     sp<AMessage> response;
485     return PostAndAwaitResponse(msg, &response);
486 }
487 
signalEndOfInputStream()488 status_t MediaCodec::signalEndOfInputStream() {
489     sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
490 
491     sp<AMessage> response;
492     return PostAndAwaitResponse(msg, &response);
493 }
494 
getOutputFormat(sp<AMessage> * format) const495 status_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
496     sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
497 
498     sp<AMessage> response;
499     status_t err;
500     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
501         return err;
502     }
503 
504     CHECK(response->findMessage("format", format));
505 
506     return OK;
507 }
508 
getInputFormat(sp<AMessage> * format) const509 status_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
510     sp<AMessage> msg = new AMessage(kWhatGetInputFormat, id());
511 
512     sp<AMessage> response;
513     status_t err;
514     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
515         return err;
516     }
517 
518     CHECK(response->findMessage("format", format));
519 
520     return OK;
521 }
522 
getName(AString * name) const523 status_t MediaCodec::getName(AString *name) const {
524     sp<AMessage> msg = new AMessage(kWhatGetName, id());
525 
526     sp<AMessage> response;
527     status_t err;
528     if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
529         return err;
530     }
531 
532     CHECK(response->findString("name", name));
533 
534     return OK;
535 }
536 
getInputBuffers(Vector<sp<ABuffer>> * buffers) const537 status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
538     sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
539     msg->setInt32("portIndex", kPortIndexInput);
540     msg->setPointer("buffers", buffers);
541 
542     sp<AMessage> response;
543     return PostAndAwaitResponse(msg, &response);
544 }
545 
getOutputBuffers(Vector<sp<ABuffer>> * buffers) const546 status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
547     sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
548     msg->setInt32("portIndex", kPortIndexOutput);
549     msg->setPointer("buffers", buffers);
550 
551     sp<AMessage> response;
552     return PostAndAwaitResponse(msg, &response);
553 }
554 
getOutputBuffer(size_t index,sp<ABuffer> * buffer)555 status_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
556     sp<AMessage> format;
557     return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
558 }
559 
getOutputFormat(size_t index,sp<AMessage> * format)560 status_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
561     sp<ABuffer> buffer;
562     return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
563 }
564 
getInputBuffer(size_t index,sp<ABuffer> * buffer)565 status_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
566     sp<AMessage> format;
567     return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
568 }
569 
isExecuting() const570 bool MediaCodec::isExecuting() const {
571     return mState == STARTED || mState == FLUSHED;
572 }
573 
getBufferAndFormat(size_t portIndex,size_t index,sp<ABuffer> * buffer,sp<AMessage> * format)574 status_t MediaCodec::getBufferAndFormat(
575         size_t portIndex, size_t index,
576         sp<ABuffer> *buffer, sp<AMessage> *format) {
577     // use mutex instead of a context switch
578 
579     buffer->clear();
580     format->clear();
581     if (!isExecuting()) {
582         return INVALID_OPERATION;
583     }
584 
585     // we do not want mPortBuffers to change during this section
586     // we also don't want mOwnedByClient to change during this
587     Mutex::Autolock al(mBufferLock);
588     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
589     if (index < buffers->size()) {
590         const BufferInfo &info = buffers->itemAt(index);
591         if (info.mOwnedByClient) {
592             // by the time buffers array is initialized, crypto is set
593             if (portIndex == kPortIndexInput && mCrypto != NULL) {
594                 *buffer = info.mEncryptedData;
595             } else {
596                 *buffer = info.mData;
597             }
598             *format = info.mFormat;
599         }
600     }
601     return OK;
602 }
603 
flush()604 status_t MediaCodec::flush() {
605     sp<AMessage> msg = new AMessage(kWhatFlush, id());
606 
607     sp<AMessage> response;
608     return PostAndAwaitResponse(msg, &response);
609 }
610 
requestIDRFrame()611 status_t MediaCodec::requestIDRFrame() {
612     (new AMessage(kWhatRequestIDRFrame, id()))->post();
613 
614     return OK;
615 }
616 
requestActivityNotification(const sp<AMessage> & notify)617 void MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
618     sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
619     msg->setMessage("notify", notify);
620     msg->post();
621 }
622 
623 ////////////////////////////////////////////////////////////////////////////////
624 
cancelPendingDequeueOperations()625 void MediaCodec::cancelPendingDequeueOperations() {
626     if (mFlags & kFlagDequeueInputPending) {
627         PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
628 
629         ++mDequeueInputTimeoutGeneration;
630         mDequeueInputReplyID = 0;
631         mFlags &= ~kFlagDequeueInputPending;
632     }
633 
634     if (mFlags & kFlagDequeueOutputPending) {
635         PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
636 
637         ++mDequeueOutputTimeoutGeneration;
638         mDequeueOutputReplyID = 0;
639         mFlags &= ~kFlagDequeueOutputPending;
640     }
641 }
642 
handleDequeueInputBuffer(uint32_t replyID,bool newRequest)643 bool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
644     if (!isExecuting() || (mFlags & kFlagIsAsync)
645             || (newRequest && (mFlags & kFlagDequeueInputPending))) {
646         PostReplyWithError(replyID, INVALID_OPERATION);
647         return true;
648     } else if (mFlags & kFlagStickyError) {
649         PostReplyWithError(replyID, getStickyError());
650         return true;
651     }
652 
653     ssize_t index = dequeuePortBuffer(kPortIndexInput);
654 
655     if (index < 0) {
656         CHECK_EQ(index, -EAGAIN);
657         return false;
658     }
659 
660     sp<AMessage> response = new AMessage;
661     response->setSize("index", index);
662     response->postReply(replyID);
663 
664     return true;
665 }
666 
handleDequeueOutputBuffer(uint32_t replyID,bool newRequest)667 bool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
668     sp<AMessage> response = new AMessage;
669 
670     if (!isExecuting() || (mFlags & kFlagIsAsync)
671             || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
672         response->setInt32("err", INVALID_OPERATION);
673     } else if (mFlags & kFlagStickyError) {
674         response->setInt32("err", getStickyError());
675     } else if (mFlags & kFlagOutputBuffersChanged) {
676         response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
677         mFlags &= ~kFlagOutputBuffersChanged;
678     } else if (mFlags & kFlagOutputFormatChanged) {
679         response->setInt32("err", INFO_FORMAT_CHANGED);
680         mFlags &= ~kFlagOutputFormatChanged;
681     } else {
682         ssize_t index = dequeuePortBuffer(kPortIndexOutput);
683 
684         if (index < 0) {
685             CHECK_EQ(index, -EAGAIN);
686             return false;
687         }
688 
689         const sp<ABuffer> &buffer =
690             mPortBuffers[kPortIndexOutput].itemAt(index).mData;
691 
692         response->setSize("index", index);
693         response->setSize("offset", buffer->offset());
694         response->setSize("size", buffer->size());
695 
696         int64_t timeUs;
697         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
698 
699         response->setInt64("timeUs", timeUs);
700 
701         int32_t omxFlags;
702         CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
703 
704         uint32_t flags = 0;
705         if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
706             flags |= BUFFER_FLAG_SYNCFRAME;
707         }
708         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
709             flags |= BUFFER_FLAG_CODECCONFIG;
710         }
711         if (omxFlags & OMX_BUFFERFLAG_EOS) {
712             flags |= BUFFER_FLAG_EOS;
713         }
714 
715         response->setInt32("flags", flags);
716     }
717 
718     response->postReply(replyID);
719 
720     return true;
721 }
722 
onMessageReceived(const sp<AMessage> & msg)723 void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
724     switch (msg->what()) {
725         case kWhatCodecNotify:
726         {
727             int32_t what;
728             CHECK(msg->findInt32("what", &what));
729 
730             switch (what) {
731                 case CodecBase::kWhatError:
732                 {
733                     int32_t err, actionCode;
734                     CHECK(msg->findInt32("err", &err));
735                     CHECK(msg->findInt32("actionCode", &actionCode));
736 
737                     ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
738                             err, actionCode, mState);
739                     if (err == DEAD_OBJECT) {
740                         mFlags |= kFlagSawMediaServerDie;
741                         mFlags &= ~kFlagIsComponentAllocated;
742                     }
743 
744                     bool sendErrorResponse = true;
745 
746                     switch (mState) {
747                         case INITIALIZING:
748                         {
749                             setState(UNINITIALIZED);
750                             break;
751                         }
752 
753                         case CONFIGURING:
754                         {
755                             setState(actionCode == ACTION_CODE_FATAL ?
756                                     UNINITIALIZED : INITIALIZED);
757                             break;
758                         }
759 
760                         case STARTING:
761                         {
762                             setState(actionCode == ACTION_CODE_FATAL ?
763                                     UNINITIALIZED : CONFIGURED);
764                             break;
765                         }
766 
767                         case STOPPING:
768                         case RELEASING:
769                         {
770                             // Ignore the error, assuming we'll still get
771                             // the shutdown complete notification.
772 
773                             sendErrorResponse = false;
774 
775                             if (mFlags & kFlagSawMediaServerDie) {
776                                 // MediaServer died, there definitely won't
777                                 // be a shutdown complete notification after
778                                 // all.
779 
780                                 // note that we're directly going from
781                                 // STOPPING->UNINITIALIZED, instead of the
782                                 // usual STOPPING->INITIALIZED state.
783                                 setState(UNINITIALIZED);
784                                 if (mState == RELEASING) {
785                                     mComponentName.clear();
786                                 }
787                                 (new AMessage)->postReply(mReplyID);
788                             }
789                             break;
790                         }
791 
792                         case FLUSHING:
793                         {
794                             if (actionCode == ACTION_CODE_FATAL) {
795                                 setState(UNINITIALIZED);
796                             } else {
797                                 setState(
798                                         (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
799                             }
800                             break;
801                         }
802 
803                         case FLUSHED:
804                         case STARTED:
805                         {
806                             sendErrorResponse = false;
807 
808                             setStickyError(err);
809                             postActivityNotificationIfPossible();
810 
811                             cancelPendingDequeueOperations();
812 
813                             if (mFlags & kFlagIsAsync) {
814                                 onError(err, actionCode);
815                             }
816                             switch (actionCode) {
817                             case ACTION_CODE_TRANSIENT:
818                                 break;
819                             case ACTION_CODE_RECOVERABLE:
820                                 setState(INITIALIZED);
821                                 break;
822                             default:
823                                 setState(UNINITIALIZED);
824                                 break;
825                             }
826                             break;
827                         }
828 
829                         default:
830                         {
831                             sendErrorResponse = false;
832 
833                             setStickyError(err);
834                             postActivityNotificationIfPossible();
835 
836                             // actionCode in an uninitialized state is always fatal.
837                             if (mState == UNINITIALIZED) {
838                                 actionCode = ACTION_CODE_FATAL;
839                             }
840                             if (mFlags & kFlagIsAsync) {
841                                 onError(err, actionCode);
842                             }
843                             switch (actionCode) {
844                             case ACTION_CODE_TRANSIENT:
845                                 break;
846                             case ACTION_CODE_RECOVERABLE:
847                                 setState(INITIALIZED);
848                                 break;
849                             default:
850                                 setState(UNINITIALIZED);
851                                 break;
852                             }
853                             break;
854                         }
855                     }
856 
857                     if (sendErrorResponse) {
858                         PostReplyWithError(mReplyID, err);
859                     }
860                     break;
861                 }
862 
863                 case CodecBase::kWhatComponentAllocated:
864                 {
865                     CHECK_EQ(mState, INITIALIZING);
866                     setState(INITIALIZED);
867                     mFlags |= kFlagIsComponentAllocated;
868 
869                     CHECK(msg->findString("componentName", &mComponentName));
870 
871                     if (mComponentName.startsWith("OMX.google.")) {
872                         mFlags |= kFlagUsesSoftwareRenderer;
873                     } else {
874                         mFlags &= ~kFlagUsesSoftwareRenderer;
875                     }
876 
877                     if (mComponentName.endsWith(".secure")) {
878                         mFlags |= kFlagIsSecure;
879                     } else {
880                         mFlags &= ~kFlagIsSecure;
881                     }
882 
883                     (new AMessage)->postReply(mReplyID);
884                     break;
885                 }
886 
887                 case CodecBase::kWhatComponentConfigured:
888                 {
889                     CHECK_EQ(mState, CONFIGURING);
890 
891                     // reset input surface flag
892                     mHaveInputSurface = false;
893 
894                     CHECK(msg->findMessage("input-format", &mInputFormat));
895                     CHECK(msg->findMessage("output-format", &mOutputFormat));
896 
897                     int32_t usingSwRenderer;
898                     if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
899                             && usingSwRenderer) {
900                         mFlags |= kFlagUsesSoftwareRenderer;
901                     }
902                     setState(CONFIGURED);
903                     (new AMessage)->postReply(mReplyID);
904                     break;
905                 }
906 
907                 case CodecBase::kWhatInputSurfaceCreated:
908                 {
909                     // response to initiateCreateInputSurface()
910                     status_t err = NO_ERROR;
911                     sp<AMessage> response = new AMessage();
912                     if (!msg->findInt32("err", &err)) {
913                         sp<RefBase> obj;
914                         msg->findObject("input-surface", &obj);
915                         CHECK(obj != NULL);
916                         response->setObject("input-surface", obj);
917                         mHaveInputSurface = true;
918                     } else {
919                         response->setInt32("err", err);
920                     }
921                     response->postReply(mReplyID);
922                     break;
923                 }
924 
925                 case CodecBase::kWhatSignaledInputEOS:
926                 {
927                     // response to signalEndOfInputStream()
928                     sp<AMessage> response = new AMessage();
929                     status_t err;
930                     if (msg->findInt32("err", &err)) {
931                         response->setInt32("err", err);
932                     }
933                     response->postReply(mReplyID);
934                     break;
935                 }
936 
937 
938                 case CodecBase::kWhatBuffersAllocated:
939                 {
940                     Mutex::Autolock al(mBufferLock);
941                     int32_t portIndex;
942                     CHECK(msg->findInt32("portIndex", &portIndex));
943 
944                     ALOGV("%s buffers allocated",
945                           portIndex == kPortIndexInput ? "input" : "output");
946 
947                     CHECK(portIndex == kPortIndexInput
948                             || portIndex == kPortIndexOutput);
949 
950                     mPortBuffers[portIndex].clear();
951 
952                     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
953 
954                     sp<RefBase> obj;
955                     CHECK(msg->findObject("portDesc", &obj));
956 
957                     sp<CodecBase::PortDescription> portDesc =
958                         static_cast<CodecBase::PortDescription *>(obj.get());
959 
960                     size_t numBuffers = portDesc->countBuffers();
961 
962                     for (size_t i = 0; i < numBuffers; ++i) {
963                         BufferInfo info;
964                         info.mBufferID = portDesc->bufferIDAt(i);
965                         info.mOwnedByClient = false;
966                         info.mData = portDesc->bufferAt(i);
967 
968                         if (portIndex == kPortIndexInput && mCrypto != NULL) {
969                             info.mEncryptedData =
970                                 new ABuffer(info.mData->capacity());
971                         }
972 
973                         buffers->push_back(info);
974                     }
975 
976                     if (portIndex == kPortIndexOutput) {
977                         if (mState == STARTING) {
978                             // We're always allocating output buffers after
979                             // allocating input buffers, so this is a good
980                             // indication that now all buffers are allocated.
981                             setState(STARTED);
982                             (new AMessage)->postReply(mReplyID);
983                         } else {
984                             mFlags |= kFlagOutputBuffersChanged;
985                             postActivityNotificationIfPossible();
986                         }
987                     }
988                     break;
989                 }
990 
991                 case CodecBase::kWhatOutputFormatChanged:
992                 {
993                     ALOGV("codec output format changed");
994 
995                     if (mSoftRenderer == NULL &&
996                             mNativeWindow != NULL &&
997                             (mFlags & kFlagUsesSoftwareRenderer)) {
998                         AString mime;
999                         CHECK(msg->findString("mime", &mime));
1000 
1001                         if (mime.startsWithIgnoreCase("video/")) {
1002                             mSoftRenderer = new SoftwareRenderer(mNativeWindow);
1003                         }
1004                     }
1005 
1006                     mOutputFormat = msg;
1007 
1008                     if (mFlags & kFlagIsEncoder) {
1009                         // Before we announce the format change we should
1010                         // collect codec specific data and amend the output
1011                         // format as necessary.
1012                         mFlags |= kFlagGatherCodecSpecificData;
1013                     } else if (mFlags & kFlagIsAsync) {
1014                         onOutputFormatChanged();
1015                     } else {
1016                         mFlags |= kFlagOutputFormatChanged;
1017                         postActivityNotificationIfPossible();
1018                     }
1019 
1020                     // Notify mCrypto of video resolution changes
1021                     if (mCrypto != NULL) {
1022                         int32_t left, top, right, bottom, width, height;
1023                         if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
1024                             mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
1025                         } else if (mOutputFormat->findInt32("width", &width)
1026                                 && mOutputFormat->findInt32("height", &height)) {
1027                             mCrypto->notifyResolution(width, height);
1028                         }
1029                     }
1030 
1031                     break;
1032                 }
1033 
1034                 case CodecBase::kWhatFillThisBuffer:
1035                 {
1036                     /* size_t index = */updateBuffers(kPortIndexInput, msg);
1037 
1038                     if (mState == FLUSHING
1039                             || mState == STOPPING
1040                             || mState == RELEASING) {
1041                         returnBuffersToCodecOnPort(kPortIndexInput);
1042                         break;
1043                     }
1044 
1045                     if (!mCSD.empty()) {
1046                         ssize_t index = dequeuePortBuffer(kPortIndexInput);
1047                         CHECK_GE(index, 0);
1048 
1049                         // If codec specific data had been specified as
1050                         // part of the format in the call to configure and
1051                         // if there's more csd left, we submit it here
1052                         // clients only get access to input buffers once
1053                         // this data has been exhausted.
1054 
1055                         status_t err = queueCSDInputBuffer(index);
1056 
1057                         if (err != OK) {
1058                             ALOGE("queueCSDInputBuffer failed w/ error %d",
1059                                   err);
1060 
1061                             setStickyError(err);
1062                             postActivityNotificationIfPossible();
1063 
1064                             cancelPendingDequeueOperations();
1065                         }
1066                         break;
1067                     }
1068 
1069                     if (mFlags & kFlagIsAsync) {
1070                         if (!mHaveInputSurface) {
1071                             onInputBufferAvailable();
1072                         }
1073                     } else if (mFlags & kFlagDequeueInputPending) {
1074                         CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
1075 
1076                         ++mDequeueInputTimeoutGeneration;
1077                         mFlags &= ~kFlagDequeueInputPending;
1078                         mDequeueInputReplyID = 0;
1079                     } else {
1080                         postActivityNotificationIfPossible();
1081                     }
1082                     break;
1083                 }
1084 
1085                 case CodecBase::kWhatDrainThisBuffer:
1086                 {
1087                     /* size_t index = */updateBuffers(kPortIndexOutput, msg);
1088 
1089                     if (mState == FLUSHING
1090                             || mState == STOPPING
1091                             || mState == RELEASING) {
1092                         returnBuffersToCodecOnPort(kPortIndexOutput);
1093                         break;
1094                     }
1095 
1096                     sp<ABuffer> buffer;
1097                     CHECK(msg->findBuffer("buffer", &buffer));
1098 
1099                     int32_t omxFlags;
1100                     CHECK(msg->findInt32("flags", &omxFlags));
1101 
1102                     buffer->meta()->setInt32("omxFlags", omxFlags);
1103 
1104                     if (mFlags & kFlagGatherCodecSpecificData) {
1105                         // This is the very first output buffer after a
1106                         // format change was signalled, it'll either contain
1107                         // the one piece of codec specific data we can expect
1108                         // or there won't be codec specific data.
1109                         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1110                             status_t err =
1111                                 amendOutputFormatWithCodecSpecificData(buffer);
1112 
1113                             if (err != OK) {
1114                                 ALOGE("Codec spit out malformed codec "
1115                                       "specific data!");
1116                             }
1117                         }
1118 
1119                         mFlags &= ~kFlagGatherCodecSpecificData;
1120                         if (mFlags & kFlagIsAsync) {
1121                             onOutputFormatChanged();
1122                         } else {
1123                             mFlags |= kFlagOutputFormatChanged;
1124                         }
1125                     }
1126 
1127                     if (mFlags & kFlagIsAsync) {
1128                         onOutputBufferAvailable();
1129                     } else if (mFlags & kFlagDequeueOutputPending) {
1130                         CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
1131 
1132                         ++mDequeueOutputTimeoutGeneration;
1133                         mFlags &= ~kFlagDequeueOutputPending;
1134                         mDequeueOutputReplyID = 0;
1135                     } else {
1136                         postActivityNotificationIfPossible();
1137                     }
1138 
1139                     break;
1140                 }
1141 
1142                 case CodecBase::kWhatEOS:
1143                 {
1144                     // We already notify the client of this by using the
1145                     // corresponding flag in "onOutputBufferReady".
1146                     break;
1147                 }
1148 
1149                 case CodecBase::kWhatShutdownCompleted:
1150                 {
1151                     if (mState == STOPPING) {
1152                         setState(INITIALIZED);
1153                     } else {
1154                         CHECK_EQ(mState, RELEASING);
1155                         setState(UNINITIALIZED);
1156                         mComponentName.clear();
1157                     }
1158                     mFlags &= ~kFlagIsComponentAllocated;
1159 
1160                     (new AMessage)->postReply(mReplyID);
1161                     break;
1162                 }
1163 
1164                 case CodecBase::kWhatFlushCompleted:
1165                 {
1166                     if (mState != FLUSHING) {
1167                         ALOGW("received FlushCompleted message in state %d",
1168                                 mState);
1169                         break;
1170                     }
1171 
1172                     if (mFlags & kFlagIsAsync) {
1173                         setState(FLUSHED);
1174                     } else {
1175                         setState(STARTED);
1176                         mCodec->signalResume();
1177                     }
1178 
1179                     (new AMessage)->postReply(mReplyID);
1180                     break;
1181                 }
1182 
1183                 default:
1184                     TRESPASS();
1185             }
1186             break;
1187         }
1188 
1189         case kWhatInit:
1190         {
1191             uint32_t replyID;
1192             CHECK(msg->senderAwaitsResponse(&replyID));
1193 
1194             if (mState != UNINITIALIZED) {
1195                 PostReplyWithError(replyID, INVALID_OPERATION);
1196                 break;
1197             }
1198 
1199             mReplyID = replyID;
1200             setState(INITIALIZING);
1201 
1202             AString name;
1203             CHECK(msg->findString("name", &name));
1204 
1205             int32_t nameIsType;
1206             int32_t encoder = false;
1207             CHECK(msg->findInt32("nameIsType", &nameIsType));
1208             if (nameIsType) {
1209                 CHECK(msg->findInt32("encoder", &encoder));
1210             }
1211 
1212             sp<AMessage> format = new AMessage;
1213 
1214             if (nameIsType) {
1215                 format->setString("mime", name.c_str());
1216                 format->setInt32("encoder", encoder);
1217             } else {
1218                 format->setString("componentName", name.c_str());
1219             }
1220 
1221             mCodec->initiateAllocateComponent(format);
1222             break;
1223         }
1224 
1225         case kWhatSetCallback:
1226         {
1227             uint32_t replyID;
1228             CHECK(msg->senderAwaitsResponse(&replyID));
1229 
1230             if (mState == UNINITIALIZED
1231                     || mState == INITIALIZING
1232                     || isExecuting()) {
1233                 // callback can't be set after codec is executing,
1234                 // or before it's initialized (as the callback
1235                 // will be cleared when it goes to INITIALIZED)
1236                 PostReplyWithError(replyID, INVALID_OPERATION);
1237                 break;
1238             }
1239 
1240             sp<AMessage> callback;
1241             CHECK(msg->findMessage("callback", &callback));
1242 
1243             mCallback = callback;
1244 
1245             if (mCallback != NULL) {
1246                 ALOGI("MediaCodec will operate in async mode");
1247                 mFlags |= kFlagIsAsync;
1248             } else {
1249                 mFlags &= ~kFlagIsAsync;
1250             }
1251 
1252             sp<AMessage> response = new AMessage;
1253             response->postReply(replyID);
1254             break;
1255         }
1256 
1257         case kWhatConfigure:
1258         {
1259             uint32_t replyID;
1260             CHECK(msg->senderAwaitsResponse(&replyID));
1261 
1262             if (mState != INITIALIZED) {
1263                 PostReplyWithError(replyID, INVALID_OPERATION);
1264                 break;
1265             }
1266 
1267             sp<RefBase> obj;
1268             if (!msg->findObject("native-window", &obj)) {
1269                 obj.clear();
1270             }
1271 
1272             sp<AMessage> format;
1273             CHECK(msg->findMessage("format", &format));
1274 
1275             if (obj != NULL) {
1276                 format->setObject("native-window", obj);
1277 
1278                 status_t err = setNativeWindow(
1279                     static_cast<NativeWindowWrapper *>(obj.get())
1280                         ->getSurfaceTextureClient());
1281 
1282                 if (err != OK) {
1283                     PostReplyWithError(replyID, err);
1284                     break;
1285                 }
1286             } else {
1287                 setNativeWindow(NULL);
1288             }
1289 
1290             mReplyID = replyID;
1291             setState(CONFIGURING);
1292 
1293             void *crypto;
1294             if (!msg->findPointer("crypto", &crypto)) {
1295                 crypto = NULL;
1296             }
1297 
1298             mCrypto = static_cast<ICrypto *>(crypto);
1299 
1300             uint32_t flags;
1301             CHECK(msg->findInt32("flags", (int32_t *)&flags));
1302 
1303             if (flags & CONFIGURE_FLAG_ENCODE) {
1304                 format->setInt32("encoder", true);
1305                 mFlags |= kFlagIsEncoder;
1306             }
1307 
1308             extractCSD(format);
1309 
1310             mCodec->initiateConfigureComponent(format);
1311             break;
1312         }
1313 
1314         case kWhatCreateInputSurface:
1315         {
1316             uint32_t replyID;
1317             CHECK(msg->senderAwaitsResponse(&replyID));
1318 
1319             // Must be configured, but can't have been started yet.
1320             if (mState != CONFIGURED) {
1321                 PostReplyWithError(replyID, INVALID_OPERATION);
1322                 break;
1323             }
1324 
1325             mReplyID = replyID;
1326             mCodec->initiateCreateInputSurface();
1327             break;
1328         }
1329 
1330         case kWhatStart:
1331         {
1332             uint32_t replyID;
1333             CHECK(msg->senderAwaitsResponse(&replyID));
1334 
1335             if (mState == FLUSHED) {
1336                 setState(STARTED);
1337                 mCodec->signalResume();
1338                 PostReplyWithError(replyID, OK);
1339                 break;
1340             } else if (mState != CONFIGURED) {
1341                 PostReplyWithError(replyID, INVALID_OPERATION);
1342                 break;
1343             }
1344 
1345             mReplyID = replyID;
1346             setState(STARTING);
1347 
1348             mCodec->initiateStart();
1349             break;
1350         }
1351 
1352         case kWhatStop:
1353         case kWhatRelease:
1354         {
1355             State targetState =
1356                 (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1357 
1358             uint32_t replyID;
1359             CHECK(msg->senderAwaitsResponse(&replyID));
1360 
1361             if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
1362                     && mState != INITIALIZED
1363                     && mState != CONFIGURED && !isExecuting()) {
1364                 // 1) Permit release to shut down the component if allocated.
1365                 //
1366                 // 2) We may be in "UNINITIALIZED" state already and
1367                 // also shutdown the encoder/decoder without the
1368                 // client being aware of this if media server died while
1369                 // we were being stopped. The client would assume that
1370                 // after stop() returned, it would be safe to call release()
1371                 // and it should be in this case, no harm to allow a release()
1372                 // if we're already uninitialized.
1373                 sp<AMessage> response = new AMessage;
1374                 status_t err = mState == targetState ? OK : INVALID_OPERATION;
1375                 response->setInt32("err", err);
1376                 if (err == OK && targetState == UNINITIALIZED) {
1377                     mComponentName.clear();
1378                 }
1379                 response->postReply(replyID);
1380                 break;
1381             }
1382 
1383             if (mFlags & kFlagSawMediaServerDie) {
1384                 // It's dead, Jim. Don't expect initiateShutdown to yield
1385                 // any useful results now...
1386                 setState(UNINITIALIZED);
1387                 if (targetState == UNINITIALIZED) {
1388                     mComponentName.clear();
1389                 }
1390                 (new AMessage)->postReply(replyID);
1391                 break;
1392             }
1393 
1394             mReplyID = replyID;
1395             setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1396 
1397             mCodec->initiateShutdown(
1398                     msg->what() == kWhatStop /* keepComponentAllocated */);
1399 
1400             returnBuffersToCodec();
1401             break;
1402         }
1403 
1404         case kWhatDequeueInputBuffer:
1405         {
1406             uint32_t replyID;
1407             CHECK(msg->senderAwaitsResponse(&replyID));
1408 
1409             if (mFlags & kFlagIsAsync) {
1410                 ALOGE("dequeueOutputBuffer can't be used in async mode");
1411                 PostReplyWithError(replyID, INVALID_OPERATION);
1412                 break;
1413             }
1414 
1415             if (mHaveInputSurface) {
1416                 ALOGE("dequeueInputBuffer can't be used with input surface");
1417                 PostReplyWithError(replyID, INVALID_OPERATION);
1418                 break;
1419             }
1420 
1421             if (handleDequeueInputBuffer(replyID, true /* new request */)) {
1422                 break;
1423             }
1424 
1425             int64_t timeoutUs;
1426             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1427 
1428             if (timeoutUs == 0ll) {
1429                 PostReplyWithError(replyID, -EAGAIN);
1430                 break;
1431             }
1432 
1433             mFlags |= kFlagDequeueInputPending;
1434             mDequeueInputReplyID = replyID;
1435 
1436             if (timeoutUs > 0ll) {
1437                 sp<AMessage> timeoutMsg =
1438                     new AMessage(kWhatDequeueInputTimedOut, id());
1439                 timeoutMsg->setInt32(
1440                         "generation", ++mDequeueInputTimeoutGeneration);
1441                 timeoutMsg->post(timeoutUs);
1442             }
1443             break;
1444         }
1445 
1446         case kWhatDequeueInputTimedOut:
1447         {
1448             int32_t generation;
1449             CHECK(msg->findInt32("generation", &generation));
1450 
1451             if (generation != mDequeueInputTimeoutGeneration) {
1452                 // Obsolete
1453                 break;
1454             }
1455 
1456             CHECK(mFlags & kFlagDequeueInputPending);
1457 
1458             PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
1459 
1460             mFlags &= ~kFlagDequeueInputPending;
1461             mDequeueInputReplyID = 0;
1462             break;
1463         }
1464 
1465         case kWhatQueueInputBuffer:
1466         {
1467             uint32_t replyID;
1468             CHECK(msg->senderAwaitsResponse(&replyID));
1469 
1470             if (!isExecuting()) {
1471                 PostReplyWithError(replyID, INVALID_OPERATION);
1472                 break;
1473             } else if (mFlags & kFlagStickyError) {
1474                 PostReplyWithError(replyID, getStickyError());
1475                 break;
1476             }
1477 
1478             status_t err = onQueueInputBuffer(msg);
1479 
1480             PostReplyWithError(replyID, err);
1481             break;
1482         }
1483 
1484         case kWhatDequeueOutputBuffer:
1485         {
1486             uint32_t replyID;
1487             CHECK(msg->senderAwaitsResponse(&replyID));
1488 
1489             if (mFlags & kFlagIsAsync) {
1490                 ALOGE("dequeueOutputBuffer can't be used in async mode");
1491                 PostReplyWithError(replyID, INVALID_OPERATION);
1492                 break;
1493             }
1494 
1495             if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
1496                 break;
1497             }
1498 
1499             int64_t timeoutUs;
1500             CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1501 
1502             if (timeoutUs == 0ll) {
1503                 PostReplyWithError(replyID, -EAGAIN);
1504                 break;
1505             }
1506 
1507             mFlags |= kFlagDequeueOutputPending;
1508             mDequeueOutputReplyID = replyID;
1509 
1510             if (timeoutUs > 0ll) {
1511                 sp<AMessage> timeoutMsg =
1512                     new AMessage(kWhatDequeueOutputTimedOut, id());
1513                 timeoutMsg->setInt32(
1514                         "generation", ++mDequeueOutputTimeoutGeneration);
1515                 timeoutMsg->post(timeoutUs);
1516             }
1517             break;
1518         }
1519 
1520         case kWhatDequeueOutputTimedOut:
1521         {
1522             int32_t generation;
1523             CHECK(msg->findInt32("generation", &generation));
1524 
1525             if (generation != mDequeueOutputTimeoutGeneration) {
1526                 // Obsolete
1527                 break;
1528             }
1529 
1530             CHECK(mFlags & kFlagDequeueOutputPending);
1531 
1532             PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
1533 
1534             mFlags &= ~kFlagDequeueOutputPending;
1535             mDequeueOutputReplyID = 0;
1536             break;
1537         }
1538 
1539         case kWhatReleaseOutputBuffer:
1540         {
1541             uint32_t replyID;
1542             CHECK(msg->senderAwaitsResponse(&replyID));
1543 
1544             if (!isExecuting()) {
1545                 PostReplyWithError(replyID, INVALID_OPERATION);
1546                 break;
1547             } else if (mFlags & kFlagStickyError) {
1548                 PostReplyWithError(replyID, getStickyError());
1549                 break;
1550             }
1551 
1552             status_t err = onReleaseOutputBuffer(msg);
1553 
1554             PostReplyWithError(replyID, err);
1555             break;
1556         }
1557 
1558         case kWhatSignalEndOfInputStream:
1559         {
1560             uint32_t replyID;
1561             CHECK(msg->senderAwaitsResponse(&replyID));
1562 
1563             if (!isExecuting()) {
1564                 PostReplyWithError(replyID, INVALID_OPERATION);
1565                 break;
1566             } else if (mFlags & kFlagStickyError) {
1567                 PostReplyWithError(replyID, getStickyError());
1568                 break;
1569             }
1570 
1571             mReplyID = replyID;
1572             mCodec->signalEndOfInputStream();
1573             break;
1574         }
1575 
1576         case kWhatGetBuffers:
1577         {
1578             uint32_t replyID;
1579             CHECK(msg->senderAwaitsResponse(&replyID));
1580 
1581             if (!isExecuting() || (mFlags & kFlagIsAsync)) {
1582                 PostReplyWithError(replyID, INVALID_OPERATION);
1583                 break;
1584             } else if (mFlags & kFlagStickyError) {
1585                 PostReplyWithError(replyID, getStickyError());
1586                 break;
1587             }
1588 
1589             int32_t portIndex;
1590             CHECK(msg->findInt32("portIndex", &portIndex));
1591 
1592             Vector<sp<ABuffer> > *dstBuffers;
1593             CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
1594 
1595             dstBuffers->clear();
1596             const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
1597 
1598             for (size_t i = 0; i < srcBuffers.size(); ++i) {
1599                 const BufferInfo &info = srcBuffers.itemAt(i);
1600 
1601                 dstBuffers->push_back(
1602                         (portIndex == kPortIndexInput && mCrypto != NULL)
1603                                 ? info.mEncryptedData : info.mData);
1604             }
1605 
1606             (new AMessage)->postReply(replyID);
1607             break;
1608         }
1609 
1610         case kWhatFlush:
1611         {
1612             uint32_t replyID;
1613             CHECK(msg->senderAwaitsResponse(&replyID));
1614 
1615             if (!isExecuting()) {
1616                 PostReplyWithError(replyID, INVALID_OPERATION);
1617                 break;
1618             } else if (mFlags & kFlagStickyError) {
1619                 PostReplyWithError(replyID, getStickyError());
1620                 break;
1621             }
1622 
1623             mReplyID = replyID;
1624             // TODO: skip flushing if already FLUSHED
1625             setState(FLUSHING);
1626 
1627             mCodec->signalFlush();
1628             returnBuffersToCodec();
1629             break;
1630         }
1631 
1632         case kWhatGetInputFormat:
1633         case kWhatGetOutputFormat:
1634         {
1635             sp<AMessage> format =
1636                 (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1637 
1638             uint32_t replyID;
1639             CHECK(msg->senderAwaitsResponse(&replyID));
1640 
1641             if ((mState != CONFIGURED && mState != STARTING &&
1642                  mState != STARTED && mState != FLUSHING &&
1643                  mState != FLUSHED)
1644                     || format == NULL) {
1645                 PostReplyWithError(replyID, INVALID_OPERATION);
1646                 break;
1647             } else if (mFlags & kFlagStickyError) {
1648                 PostReplyWithError(replyID, getStickyError());
1649                 break;
1650             }
1651 
1652             sp<AMessage> response = new AMessage;
1653             response->setMessage("format", format);
1654             response->postReply(replyID);
1655             break;
1656         }
1657 
1658         case kWhatRequestIDRFrame:
1659         {
1660             mCodec->signalRequestIDRFrame();
1661             break;
1662         }
1663 
1664         case kWhatRequestActivityNotification:
1665         {
1666             CHECK(mActivityNotify == NULL);
1667             CHECK(msg->findMessage("notify", &mActivityNotify));
1668 
1669             postActivityNotificationIfPossible();
1670             break;
1671         }
1672 
1673         case kWhatGetName:
1674         {
1675             uint32_t replyID;
1676             CHECK(msg->senderAwaitsResponse(&replyID));
1677 
1678             if (mComponentName.empty()) {
1679                 PostReplyWithError(replyID, INVALID_OPERATION);
1680                 break;
1681             }
1682 
1683             sp<AMessage> response = new AMessage;
1684             response->setString("name", mComponentName.c_str());
1685             response->postReply(replyID);
1686             break;
1687         }
1688 
1689         case kWhatSetParameters:
1690         {
1691             uint32_t replyID;
1692             CHECK(msg->senderAwaitsResponse(&replyID));
1693 
1694             sp<AMessage> params;
1695             CHECK(msg->findMessage("params", &params));
1696 
1697             status_t err = onSetParameters(params);
1698 
1699             PostReplyWithError(replyID, err);
1700             break;
1701         }
1702 
1703         default:
1704             TRESPASS();
1705     }
1706 }
1707 
extractCSD(const sp<AMessage> & format)1708 void MediaCodec::extractCSD(const sp<AMessage> &format) {
1709     mCSD.clear();
1710 
1711     size_t i = 0;
1712     for (;;) {
1713         sp<ABuffer> csd;
1714         if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
1715             break;
1716         }
1717 
1718         mCSD.push_back(csd);
1719         ++i;
1720     }
1721 
1722     ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
1723 }
1724 
queueCSDInputBuffer(size_t bufferIndex)1725 status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
1726     CHECK(!mCSD.empty());
1727 
1728     const BufferInfo *info =
1729         &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
1730 
1731     sp<ABuffer> csd = *mCSD.begin();
1732     mCSD.erase(mCSD.begin());
1733 
1734     const sp<ABuffer> &codecInputData =
1735         (mCrypto != NULL) ? info->mEncryptedData : info->mData;
1736 
1737     if (csd->size() > codecInputData->capacity()) {
1738         return -EINVAL;
1739     }
1740 
1741     memcpy(codecInputData->data(), csd->data(), csd->size());
1742 
1743     AString errorDetailMsg;
1744 
1745     sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
1746     msg->setSize("index", bufferIndex);
1747     msg->setSize("offset", 0);
1748     msg->setSize("size", csd->size());
1749     msg->setInt64("timeUs", 0ll);
1750     msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
1751     msg->setPointer("errorDetailMsg", &errorDetailMsg);
1752 
1753     return onQueueInputBuffer(msg);
1754 }
1755 
setState(State newState)1756 void MediaCodec::setState(State newState) {
1757     if (newState == INITIALIZED || newState == UNINITIALIZED) {
1758         delete mSoftRenderer;
1759         mSoftRenderer = NULL;
1760 
1761         mCrypto.clear();
1762         setNativeWindow(NULL);
1763 
1764         mInputFormat.clear();
1765         mOutputFormat.clear();
1766         mFlags &= ~kFlagOutputFormatChanged;
1767         mFlags &= ~kFlagOutputBuffersChanged;
1768         mFlags &= ~kFlagStickyError;
1769         mFlags &= ~kFlagIsEncoder;
1770         mFlags &= ~kFlagGatherCodecSpecificData;
1771         mFlags &= ~kFlagIsAsync;
1772         mStickyError = OK;
1773 
1774         mActivityNotify.clear();
1775         mCallback.clear();
1776     }
1777 
1778     if (newState == UNINITIALIZED) {
1779         // return any straggling buffers, e.g. if we got here on an error
1780         returnBuffersToCodec();
1781 
1782         // The component is gone, mediaserver's probably back up already
1783         // but should definitely be back up should we try to instantiate
1784         // another component.. and the cycle continues.
1785         mFlags &= ~kFlagSawMediaServerDie;
1786     }
1787 
1788     mState = newState;
1789 
1790     cancelPendingDequeueOperations();
1791 
1792     updateBatteryStat();
1793 }
1794 
returnBuffersToCodec()1795 void MediaCodec::returnBuffersToCodec() {
1796     returnBuffersToCodecOnPort(kPortIndexInput);
1797     returnBuffersToCodecOnPort(kPortIndexOutput);
1798 }
1799 
returnBuffersToCodecOnPort(int32_t portIndex)1800 void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
1801     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1802     Mutex::Autolock al(mBufferLock);
1803 
1804     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1805 
1806     for (size_t i = 0; i < buffers->size(); ++i) {
1807         BufferInfo *info = &buffers->editItemAt(i);
1808 
1809         if (info->mNotify != NULL) {
1810             sp<AMessage> msg = info->mNotify;
1811             info->mNotify = NULL;
1812             info->mOwnedByClient = false;
1813 
1814             if (portIndex == kPortIndexInput) {
1815                 /* no error, just returning buffers */
1816                 msg->setInt32("err", OK);
1817             }
1818             msg->post();
1819         }
1820     }
1821 
1822     mAvailPortBuffers[portIndex].clear();
1823 }
1824 
updateBuffers(int32_t portIndex,const sp<AMessage> & msg)1825 size_t MediaCodec::updateBuffers(
1826         int32_t portIndex, const sp<AMessage> &msg) {
1827     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1828 
1829     uint32_t bufferID;
1830     CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
1831 
1832     Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1833 
1834     for (size_t i = 0; i < buffers->size(); ++i) {
1835         BufferInfo *info = &buffers->editItemAt(i);
1836 
1837         if (info->mBufferID == bufferID) {
1838             CHECK(info->mNotify == NULL);
1839             CHECK(msg->findMessage("reply", &info->mNotify));
1840 
1841             info->mFormat =
1842                 (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
1843             mAvailPortBuffers[portIndex].push_back(i);
1844 
1845             return i;
1846         }
1847     }
1848 
1849     TRESPASS();
1850 
1851     return 0;
1852 }
1853 
onQueueInputBuffer(const sp<AMessage> & msg)1854 status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
1855     size_t index;
1856     size_t offset;
1857     size_t size;
1858     int64_t timeUs;
1859     uint32_t flags;
1860     CHECK(msg->findSize("index", &index));
1861     CHECK(msg->findSize("offset", &offset));
1862     CHECK(msg->findInt64("timeUs", &timeUs));
1863     CHECK(msg->findInt32("flags", (int32_t *)&flags));
1864 
1865     const CryptoPlugin::SubSample *subSamples;
1866     size_t numSubSamples;
1867     const uint8_t *key;
1868     const uint8_t *iv;
1869     CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
1870 
1871     // We allow the simpler queueInputBuffer API to be used even in
1872     // secure mode, by fabricating a single unencrypted subSample.
1873     CryptoPlugin::SubSample ss;
1874 
1875     if (msg->findSize("size", &size)) {
1876         if (mCrypto != NULL) {
1877             ss.mNumBytesOfClearData = size;
1878             ss.mNumBytesOfEncryptedData = 0;
1879 
1880             subSamples = &ss;
1881             numSubSamples = 1;
1882             key = NULL;
1883             iv = NULL;
1884         }
1885     } else {
1886         if (mCrypto == NULL) {
1887             return -EINVAL;
1888         }
1889 
1890         CHECK(msg->findPointer("subSamples", (void **)&subSamples));
1891         CHECK(msg->findSize("numSubSamples", &numSubSamples));
1892         CHECK(msg->findPointer("key", (void **)&key));
1893         CHECK(msg->findPointer("iv", (void **)&iv));
1894 
1895         int32_t tmp;
1896         CHECK(msg->findInt32("mode", &tmp));
1897 
1898         mode = (CryptoPlugin::Mode)tmp;
1899 
1900         size = 0;
1901         for (size_t i = 0; i < numSubSamples; ++i) {
1902             size += subSamples[i].mNumBytesOfClearData;
1903             size += subSamples[i].mNumBytesOfEncryptedData;
1904         }
1905     }
1906 
1907     if (index >= mPortBuffers[kPortIndexInput].size()) {
1908         return -ERANGE;
1909     }
1910 
1911     BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
1912 
1913     if (info->mNotify == NULL || !info->mOwnedByClient) {
1914         return -EACCES;
1915     }
1916 
1917     if (offset + size > info->mData->capacity()) {
1918         return -EINVAL;
1919     }
1920 
1921     sp<AMessage> reply = info->mNotify;
1922     info->mData->setRange(offset, size);
1923     info->mData->meta()->setInt64("timeUs", timeUs);
1924 
1925     if (flags & BUFFER_FLAG_EOS) {
1926         info->mData->meta()->setInt32("eos", true);
1927     }
1928 
1929     if (flags & BUFFER_FLAG_CODECCONFIG) {
1930         info->mData->meta()->setInt32("csd", true);
1931     }
1932 
1933     if (mCrypto != NULL) {
1934         if (size > info->mEncryptedData->capacity()) {
1935             return -ERANGE;
1936         }
1937 
1938         AString *errorDetailMsg;
1939         CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
1940 
1941         ssize_t result = mCrypto->decrypt(
1942                 (mFlags & kFlagIsSecure) != 0,
1943                 key,
1944                 iv,
1945                 mode,
1946                 info->mEncryptedData->base() + offset,
1947                 subSamples,
1948                 numSubSamples,
1949                 info->mData->base(),
1950                 errorDetailMsg);
1951 
1952         if (result < 0) {
1953             return result;
1954         }
1955 
1956         info->mData->setRange(0, result);
1957     }
1958 
1959     // synchronization boundary for getBufferAndFormat
1960     {
1961         Mutex::Autolock al(mBufferLock);
1962         info->mOwnedByClient = false;
1963     }
1964     reply->setBuffer("buffer", info->mData);
1965     reply->post();
1966 
1967     info->mNotify = NULL;
1968 
1969     return OK;
1970 }
1971 
onReleaseOutputBuffer(const sp<AMessage> & msg)1972 status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
1973     size_t index;
1974     CHECK(msg->findSize("index", &index));
1975 
1976     int32_t render;
1977     if (!msg->findInt32("render", &render)) {
1978         render = 0;
1979     }
1980 
1981     if (!isExecuting()) {
1982         return -EINVAL;
1983     }
1984 
1985     if (index >= mPortBuffers[kPortIndexOutput].size()) {
1986         return -ERANGE;
1987     }
1988 
1989     BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
1990 
1991     if (info->mNotify == NULL || !info->mOwnedByClient) {
1992         return -EACCES;
1993     }
1994 
1995     // synchronization boundary for getBufferAndFormat
1996     {
1997         Mutex::Autolock al(mBufferLock);
1998         info->mOwnedByClient = false;
1999     }
2000 
2001     if (render && info->mData != NULL && info->mData->size() != 0) {
2002         info->mNotify->setInt32("render", true);
2003 
2004         int64_t timestampNs = 0;
2005         if (msg->findInt64("timestampNs", &timestampNs)) {
2006             info->mNotify->setInt64("timestampNs", timestampNs);
2007         } else {
2008             // TODO: it seems like we should use the timestamp
2009             // in the (media)buffer as it potentially came from
2010             // an input surface, but we did not propagate it prior to
2011             // API 20.  Perhaps check for target SDK version.
2012 #if 0
2013             if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
2014                 ALOGV("using buffer PTS of %" PRId64, timestampNs);
2015                 timestampNs *= 1000;
2016             }
2017 #endif
2018         }
2019 
2020         if (mSoftRenderer != NULL) {
2021             mSoftRenderer->render(
2022                     info->mData->data(), info->mData->size(),
2023                     timestampNs, NULL, info->mFormat);
2024         }
2025     }
2026 
2027     info->mNotify->post();
2028     info->mNotify = NULL;
2029 
2030     return OK;
2031 }
2032 
dequeuePortBuffer(int32_t portIndex)2033 ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
2034     CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
2035 
2036     List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
2037 
2038     if (availBuffers->empty()) {
2039         return -EAGAIN;
2040     }
2041 
2042     size_t index = *availBuffers->begin();
2043     availBuffers->erase(availBuffers->begin());
2044 
2045     BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
2046     CHECK(!info->mOwnedByClient);
2047     {
2048         Mutex::Autolock al(mBufferLock);
2049         info->mOwnedByClient = true;
2050 
2051         // set image-data
2052         if (info->mFormat != NULL) {
2053             sp<ABuffer> imageData;
2054             if (info->mFormat->findBuffer("image-data", &imageData)) {
2055                 info->mData->meta()->setBuffer("image-data", imageData);
2056             }
2057             int32_t left, top, right, bottom;
2058             if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
2059                 info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
2060             }
2061         }
2062     }
2063 
2064     return index;
2065 }
2066 
setNativeWindow(const sp<Surface> & surfaceTextureClient)2067 status_t MediaCodec::setNativeWindow(
2068         const sp<Surface> &surfaceTextureClient) {
2069     status_t err;
2070 
2071     if (mNativeWindow != NULL) {
2072         err = native_window_api_disconnect(
2073                 mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
2074 
2075         if (err != OK) {
2076             ALOGW("native_window_api_disconnect returned an error: %s (%d)",
2077                     strerror(-err), err);
2078         }
2079 
2080         mNativeWindow.clear();
2081     }
2082 
2083     if (surfaceTextureClient != NULL) {
2084         err = native_window_api_connect(
2085                 surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
2086 
2087         if (err != OK) {
2088             ALOGE("native_window_api_connect returned an error: %s (%d)",
2089                     strerror(-err), err);
2090 
2091             return err;
2092         }
2093 
2094         mNativeWindow = surfaceTextureClient;
2095     }
2096 
2097     return OK;
2098 }
2099 
onInputBufferAvailable()2100 void MediaCodec::onInputBufferAvailable() {
2101     int32_t index;
2102     while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2103         sp<AMessage> msg = mCallback->dup();
2104         msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2105         msg->setInt32("index", index);
2106         msg->post();
2107     }
2108 }
2109 
onOutputBufferAvailable()2110 void MediaCodec::onOutputBufferAvailable() {
2111     int32_t index;
2112     while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2113         const sp<ABuffer> &buffer =
2114             mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2115         sp<AMessage> msg = mCallback->dup();
2116         msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2117         msg->setInt32("index", index);
2118         msg->setSize("offset", buffer->offset());
2119         msg->setSize("size", buffer->size());
2120 
2121         int64_t timeUs;
2122         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2123 
2124         msg->setInt64("timeUs", timeUs);
2125 
2126         int32_t omxFlags;
2127         CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2128 
2129         uint32_t flags = 0;
2130         if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2131             flags |= BUFFER_FLAG_SYNCFRAME;
2132         }
2133         if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2134             flags |= BUFFER_FLAG_CODECCONFIG;
2135         }
2136         if (omxFlags & OMX_BUFFERFLAG_EOS) {
2137             flags |= BUFFER_FLAG_EOS;
2138         }
2139 
2140         msg->setInt32("flags", flags);
2141 
2142         msg->post();
2143     }
2144 }
2145 
onError(status_t err,int32_t actionCode,const char * detail)2146 void MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2147     if (mCallback != NULL) {
2148         sp<AMessage> msg = mCallback->dup();
2149         msg->setInt32("callbackID", CB_ERROR);
2150         msg->setInt32("err", err);
2151         msg->setInt32("actionCode", actionCode);
2152 
2153         if (detail != NULL) {
2154             msg->setString("detail", detail);
2155         }
2156 
2157         msg->post();
2158     }
2159 }
2160 
onOutputFormatChanged()2161 void MediaCodec::onOutputFormatChanged() {
2162     if (mCallback != NULL) {
2163         sp<AMessage> msg = mCallback->dup();
2164         msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2165         msg->setMessage("format", mOutputFormat);
2166         msg->post();
2167     }
2168 }
2169 
2170 
postActivityNotificationIfPossible()2171 void MediaCodec::postActivityNotificationIfPossible() {
2172     if (mActivityNotify == NULL) {
2173         return;
2174     }
2175 
2176     bool isErrorOrOutputChanged =
2177             (mFlags & (kFlagStickyError
2178                     | kFlagOutputBuffersChanged
2179                     | kFlagOutputFormatChanged));
2180 
2181     if (isErrorOrOutputChanged
2182             || !mAvailPortBuffers[kPortIndexInput].empty()
2183             || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2184         mActivityNotify->setInt32("input-buffers",
2185                 mAvailPortBuffers[kPortIndexInput].size());
2186 
2187         if (isErrorOrOutputChanged) {
2188             // we want consumer to dequeue as many times as it can
2189             mActivityNotify->setInt32("output-buffers", INT32_MAX);
2190         } else {
2191             mActivityNotify->setInt32("output-buffers",
2192                     mAvailPortBuffers[kPortIndexOutput].size());
2193         }
2194         mActivityNotify->post();
2195         mActivityNotify.clear();
2196     }
2197 }
2198 
setParameters(const sp<AMessage> & params)2199 status_t MediaCodec::setParameters(const sp<AMessage> &params) {
2200     sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
2201     msg->setMessage("params", params);
2202 
2203     sp<AMessage> response;
2204     return PostAndAwaitResponse(msg, &response);
2205 }
2206 
onSetParameters(const sp<AMessage> & params)2207 status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2208     mCodec->signalSetParameters(params);
2209 
2210     return OK;
2211 }
2212 
amendOutputFormatWithCodecSpecificData(const sp<ABuffer> & buffer)2213 status_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2214         const sp<ABuffer> &buffer) {
2215     AString mime;
2216     CHECK(mOutputFormat->findString("mime", &mime));
2217 
2218     if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2219         // Codec specific data should be SPS and PPS in a single buffer,
2220         // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2221         // We separate the two and put them into the output format
2222         // under the keys "csd-0" and "csd-1".
2223 
2224         unsigned csdIndex = 0;
2225 
2226         const uint8_t *data = buffer->data();
2227         size_t size = buffer->size();
2228 
2229         const uint8_t *nalStart;
2230         size_t nalSize;
2231         while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2232             sp<ABuffer> csd = new ABuffer(nalSize + 4);
2233             memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2234             memcpy(csd->data() + 4, nalStart, nalSize);
2235 
2236             mOutputFormat->setBuffer(
2237                     StringPrintf("csd-%u", csdIndex).c_str(), csd);
2238 
2239             ++csdIndex;
2240         }
2241 
2242         if (csdIndex != 2) {
2243             return ERROR_MALFORMED;
2244         }
2245     } else {
2246         // For everything else we just stash the codec specific data into
2247         // the output format as a single piece of csd under "csd-0".
2248         mOutputFormat->setBuffer("csd-0", buffer);
2249     }
2250 
2251     return OK;
2252 }
2253 
updateBatteryStat()2254 void MediaCodec::updateBatteryStat() {
2255     if (mState == CONFIGURED && !mBatteryStatNotified) {
2256         AString mime;
2257         CHECK(mOutputFormat != NULL &&
2258                 mOutputFormat->findString("mime", &mime));
2259 
2260         mIsVideo = mime.startsWithIgnoreCase("video/");
2261 
2262         BatteryNotifier& notifier(BatteryNotifier::getInstance());
2263 
2264         if (mIsVideo) {
2265             notifier.noteStartVideo();
2266         } else {
2267             notifier.noteStartAudio();
2268         }
2269 
2270         mBatteryStatNotified = true;
2271     } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
2272         BatteryNotifier& notifier(BatteryNotifier::getInstance());
2273 
2274         if (mIsVideo) {
2275             notifier.noteStopVideo();
2276         } else {
2277             notifier.noteStopAudio();
2278         }
2279 
2280         mBatteryStatNotified = false;
2281     }
2282 }
2283 
2284 }  // namespace android
2285