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