MediaCodec.cpp revision db93079daf06a94e50622d0383b9ed8e767e2f92
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::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const {
614    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
615    msg->setInt32("portIndex", kPortIndexInput);
616    msg->setPointer("buffers", buffers);
617    msg->setInt32("widevine", true);
618
619    sp<AMessage> response;
620    return PostAndAwaitResponse(msg, &response);
621}
622
623status_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
624    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
625    msg->setInt32("portIndex", kPortIndexInput);
626    msg->setPointer("buffers", buffers);
627
628    sp<AMessage> response;
629    return PostAndAwaitResponse(msg, &response);
630}
631
632status_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
633    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
634    msg->setInt32("portIndex", kPortIndexOutput);
635    msg->setPointer("buffers", buffers);
636
637    sp<AMessage> response;
638    return PostAndAwaitResponse(msg, &response);
639}
640
641status_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
642    sp<AMessage> format;
643    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
644}
645
646status_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
647    sp<ABuffer> buffer;
648    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
649}
650
651status_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
652    sp<AMessage> format;
653    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
654}
655
656bool MediaCodec::isExecuting() const {
657    return mState == STARTED || mState == FLUSHED;
658}
659
660status_t MediaCodec::getBufferAndFormat(
661        size_t portIndex, size_t index,
662        sp<ABuffer> *buffer, sp<AMessage> *format) {
663    // use mutex instead of a context switch
664
665    buffer->clear();
666    format->clear();
667    if (!isExecuting()) {
668        return INVALID_OPERATION;
669    }
670
671    // we do not want mPortBuffers to change during this section
672    // we also don't want mOwnedByClient to change during this
673    Mutex::Autolock al(mBufferLock);
674    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
675    if (index < buffers->size()) {
676        const BufferInfo &info = buffers->itemAt(index);
677        if (info.mOwnedByClient) {
678            // by the time buffers array is initialized, crypto is set
679            if (portIndex == kPortIndexInput && mCrypto != NULL) {
680                *buffer = info.mEncryptedData;
681            } else {
682                *buffer = info.mData;
683            }
684            *format = info.mFormat;
685        }
686    }
687    return OK;
688}
689
690status_t MediaCodec::flush() {
691    sp<AMessage> msg = new AMessage(kWhatFlush, this);
692
693    sp<AMessage> response;
694    return PostAndAwaitResponse(msg, &response);
695}
696
697status_t MediaCodec::requestIDRFrame() {
698    (new AMessage(kWhatRequestIDRFrame, this))->post();
699
700    return OK;
701}
702
703void MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
704    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
705    msg->setMessage("notify", notify);
706    msg->post();
707}
708
709////////////////////////////////////////////////////////////////////////////////
710
711void MediaCodec::cancelPendingDequeueOperations() {
712    if (mFlags & kFlagDequeueInputPending) {
713        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
714
715        ++mDequeueInputTimeoutGeneration;
716        mDequeueInputReplyID = 0;
717        mFlags &= ~kFlagDequeueInputPending;
718    }
719
720    if (mFlags & kFlagDequeueOutputPending) {
721        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
722
723        ++mDequeueOutputTimeoutGeneration;
724        mDequeueOutputReplyID = 0;
725        mFlags &= ~kFlagDequeueOutputPending;
726    }
727}
728
729bool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
730    if (!isExecuting() || (mFlags & kFlagIsAsync)
731            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
732        PostReplyWithError(replyID, INVALID_OPERATION);
733        return true;
734    } else if (mFlags & kFlagStickyError) {
735        PostReplyWithError(replyID, getStickyError());
736        return true;
737    }
738
739    ssize_t index = dequeuePortBuffer(kPortIndexInput);
740
741    if (index < 0) {
742        CHECK_EQ(index, -EAGAIN);
743        return false;
744    }
745
746    sp<AMessage> response = new AMessage;
747    response->setSize("index", index);
748    response->postReply(replyID);
749
750    return true;
751}
752
753bool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
754    sp<AMessage> response = new AMessage;
755
756    if (!isExecuting() || (mFlags & kFlagIsAsync)
757            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
758        response->setInt32("err", INVALID_OPERATION);
759    } else if (mFlags & kFlagStickyError) {
760        response->setInt32("err", getStickyError());
761    } else if (mFlags & kFlagOutputBuffersChanged) {
762        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
763        mFlags &= ~kFlagOutputBuffersChanged;
764    } else if (mFlags & kFlagOutputFormatChanged) {
765        response->setInt32("err", INFO_FORMAT_CHANGED);
766        mFlags &= ~kFlagOutputFormatChanged;
767    } else {
768        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
769
770        if (index < 0) {
771            CHECK_EQ(index, -EAGAIN);
772            return false;
773        }
774
775        const sp<ABuffer> &buffer =
776            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
777
778        response->setSize("index", index);
779        response->setSize("offset", buffer->offset());
780        response->setSize("size", buffer->size());
781
782        int64_t timeUs;
783        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
784
785        response->setInt64("timeUs", timeUs);
786
787        int32_t omxFlags;
788        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
789
790        uint32_t flags = 0;
791        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
792            flags |= BUFFER_FLAG_SYNCFRAME;
793        }
794        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
795            flags |= BUFFER_FLAG_CODECCONFIG;
796        }
797        if (omxFlags & OMX_BUFFERFLAG_EOS) {
798            flags |= BUFFER_FLAG_EOS;
799        }
800
801        response->setInt32("flags", flags);
802    }
803
804    response->postReply(replyID);
805
806    return true;
807}
808
809void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
810    switch (msg->what()) {
811        case kWhatCodecNotify:
812        {
813            int32_t what;
814            CHECK(msg->findInt32("what", &what));
815
816            switch (what) {
817                case CodecBase::kWhatError:
818                {
819                    int32_t err, actionCode;
820                    CHECK(msg->findInt32("err", &err));
821                    CHECK(msg->findInt32("actionCode", &actionCode));
822
823                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
824                            err, actionCode, mState);
825                    if (err == DEAD_OBJECT) {
826                        mFlags |= kFlagSawMediaServerDie;
827                        mFlags &= ~kFlagIsComponentAllocated;
828                    }
829
830                    bool sendErrorResponse = true;
831
832                    switch (mState) {
833                        case INITIALIZING:
834                        {
835                            setState(UNINITIALIZED);
836                            break;
837                        }
838
839                        case CONFIGURING:
840                        {
841                            setState(actionCode == ACTION_CODE_FATAL ?
842                                    UNINITIALIZED : INITIALIZED);
843                            break;
844                        }
845
846                        case STARTING:
847                        {
848                            setState(actionCode == ACTION_CODE_FATAL ?
849                                    UNINITIALIZED : CONFIGURED);
850                            break;
851                        }
852
853                        case STOPPING:
854                        case RELEASING:
855                        {
856                            // Ignore the error, assuming we'll still get
857                            // the shutdown complete notification.
858
859                            sendErrorResponse = false;
860
861                            if (mFlags & kFlagSawMediaServerDie) {
862                                // MediaServer died, there definitely won't
863                                // be a shutdown complete notification after
864                                // all.
865
866                                // note that we're directly going from
867                                // STOPPING->UNINITIALIZED, instead of the
868                                // usual STOPPING->INITIALIZED state.
869                                setState(UNINITIALIZED);
870                                if (mState == RELEASING) {
871                                    mComponentName.clear();
872                                }
873                                (new AMessage)->postReply(mReplyID);
874                            }
875                            break;
876                        }
877
878                        case FLUSHING:
879                        {
880                            if (actionCode == ACTION_CODE_FATAL) {
881                                setState(UNINITIALIZED);
882                            } else {
883                                setState(
884                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
885                            }
886                            break;
887                        }
888
889                        case FLUSHED:
890                        case STARTED:
891                        {
892                            sendErrorResponse = false;
893
894                            setStickyError(err);
895                            postActivityNotificationIfPossible();
896
897                            cancelPendingDequeueOperations();
898
899                            if (mFlags & kFlagIsAsync) {
900                                onError(err, actionCode);
901                            }
902                            switch (actionCode) {
903                            case ACTION_CODE_TRANSIENT:
904                                break;
905                            case ACTION_CODE_RECOVERABLE:
906                                setState(INITIALIZED);
907                                break;
908                            default:
909                                setState(UNINITIALIZED);
910                                break;
911                            }
912                            break;
913                        }
914
915                        default:
916                        {
917                            sendErrorResponse = false;
918
919                            setStickyError(err);
920                            postActivityNotificationIfPossible();
921
922                            // actionCode in an uninitialized state is always fatal.
923                            if (mState == UNINITIALIZED) {
924                                actionCode = ACTION_CODE_FATAL;
925                            }
926                            if (mFlags & kFlagIsAsync) {
927                                onError(err, actionCode);
928                            }
929                            switch (actionCode) {
930                            case ACTION_CODE_TRANSIENT:
931                                break;
932                            case ACTION_CODE_RECOVERABLE:
933                                setState(INITIALIZED);
934                                break;
935                            default:
936                                setState(UNINITIALIZED);
937                                break;
938                            }
939                            break;
940                        }
941                    }
942
943                    if (sendErrorResponse) {
944                        PostReplyWithError(mReplyID, err);
945                    }
946                    break;
947                }
948
949                case CodecBase::kWhatComponentAllocated:
950                {
951                    CHECK_EQ(mState, INITIALIZING);
952                    setState(INITIALIZED);
953                    mFlags |= kFlagIsComponentAllocated;
954
955                    CHECK(msg->findString("componentName", &mComponentName));
956
957                    if (mComponentName.startsWith("OMX.google.")) {
958                        mFlags |= kFlagUsesSoftwareRenderer;
959                    } else {
960                        mFlags &= ~kFlagUsesSoftwareRenderer;
961                    }
962
963                    if (mComponentName.endsWith(".secure")) {
964                        mFlags |= kFlagIsSecure;
965                    } else {
966                        mFlags &= ~kFlagIsSecure;
967                    }
968
969                    (new AMessage)->postReply(mReplyID);
970                    break;
971                }
972
973                case CodecBase::kWhatComponentConfigured:
974                {
975                    CHECK_EQ(mState, CONFIGURING);
976
977                    // reset input surface flag
978                    mHaveInputSurface = false;
979
980                    CHECK(msg->findMessage("input-format", &mInputFormat));
981                    CHECK(msg->findMessage("output-format", &mOutputFormat));
982
983                    int32_t usingSwRenderer;
984                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
985                            && usingSwRenderer) {
986                        mFlags |= kFlagUsesSoftwareRenderer;
987                    }
988                    setState(CONFIGURED);
989                    (new AMessage)->postReply(mReplyID);
990                    break;
991                }
992
993                case CodecBase::kWhatInputSurfaceCreated:
994                {
995                    // response to initiateCreateInputSurface()
996                    status_t err = NO_ERROR;
997                    sp<AMessage> response = new AMessage();
998                    if (!msg->findInt32("err", &err)) {
999                        sp<RefBase> obj;
1000                        msg->findObject("input-surface", &obj);
1001                        CHECK(obj != NULL);
1002                        response->setObject("input-surface", obj);
1003                        mHaveInputSurface = true;
1004                    } else {
1005                        response->setInt32("err", err);
1006                    }
1007                    response->postReply(mReplyID);
1008                    break;
1009                }
1010
1011                case CodecBase::kWhatSignaledInputEOS:
1012                {
1013                    // response to signalEndOfInputStream()
1014                    sp<AMessage> response = new AMessage();
1015                    status_t err;
1016                    if (msg->findInt32("err", &err)) {
1017                        response->setInt32("err", err);
1018                    }
1019                    response->postReply(mReplyID);
1020                    break;
1021                }
1022
1023
1024                case CodecBase::kWhatBuffersAllocated:
1025                {
1026                    Mutex::Autolock al(mBufferLock);
1027                    int32_t portIndex;
1028                    CHECK(msg->findInt32("portIndex", &portIndex));
1029
1030                    ALOGV("%s buffers allocated",
1031                          portIndex == kPortIndexInput ? "input" : "output");
1032
1033                    CHECK(portIndex == kPortIndexInput
1034                            || portIndex == kPortIndexOutput);
1035
1036                    mPortBuffers[portIndex].clear();
1037
1038                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1039
1040                    sp<RefBase> obj;
1041                    CHECK(msg->findObject("portDesc", &obj));
1042
1043                    sp<CodecBase::PortDescription> portDesc =
1044                        static_cast<CodecBase::PortDescription *>(obj.get());
1045
1046                    size_t numBuffers = portDesc->countBuffers();
1047
1048                    size_t totalSize = 0;
1049                    for (size_t i = 0; i < numBuffers; ++i) {
1050                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1051                            totalSize += portDesc->bufferAt(i)->capacity();
1052                        }
1053                    }
1054
1055                    if (totalSize) {
1056                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1057                    }
1058
1059                    for (size_t i = 0; i < numBuffers; ++i) {
1060                        BufferInfo info;
1061                        info.mBufferID = portDesc->bufferIDAt(i);
1062                        info.mOwnedByClient = false;
1063                        info.mData = portDesc->bufferAt(i);
1064
1065                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1066                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1067                            info.mEncryptedData =
1068                                new ABuffer(mem->pointer(), info.mData->capacity());
1069                            info.mSharedEncryptedBuffer = mem;
1070                        }
1071
1072                        buffers->push_back(info);
1073                    }
1074
1075                    if (portIndex == kPortIndexOutput) {
1076                        if (mState == STARTING) {
1077                            // We're always allocating output buffers after
1078                            // allocating input buffers, so this is a good
1079                            // indication that now all buffers are allocated.
1080                            setState(STARTED);
1081                            (new AMessage)->postReply(mReplyID);
1082                        } else {
1083                            mFlags |= kFlagOutputBuffersChanged;
1084                            postActivityNotificationIfPossible();
1085                        }
1086                    }
1087                    break;
1088                }
1089
1090                case CodecBase::kWhatOutputFormatChanged:
1091                {
1092                    ALOGV("codec output format changed");
1093
1094                    if (mSoftRenderer == NULL &&
1095                            mNativeWindow != NULL &&
1096                            (mFlags & kFlagUsesSoftwareRenderer)) {
1097                        AString mime;
1098                        CHECK(msg->findString("mime", &mime));
1099
1100                        if (mime.startsWithIgnoreCase("video/")) {
1101                            mSoftRenderer = new SoftwareRenderer(mNativeWindow);
1102                        }
1103                    }
1104
1105                    mOutputFormat = msg;
1106
1107                    if (mFlags & kFlagIsEncoder) {
1108                        // Before we announce the format change we should
1109                        // collect codec specific data and amend the output
1110                        // format as necessary.
1111                        mFlags |= kFlagGatherCodecSpecificData;
1112                    } else if (mFlags & kFlagIsAsync) {
1113                        onOutputFormatChanged();
1114                    } else {
1115                        mFlags |= kFlagOutputFormatChanged;
1116                        postActivityNotificationIfPossible();
1117                    }
1118
1119                    // Notify mCrypto of video resolution changes
1120                    if (mCrypto != NULL) {
1121                        int32_t left, top, right, bottom, width, height;
1122                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
1123                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
1124                        } else if (mOutputFormat->findInt32("width", &width)
1125                                && mOutputFormat->findInt32("height", &height)) {
1126                            mCrypto->notifyResolution(width, height);
1127                        }
1128                    }
1129
1130                    break;
1131                }
1132
1133                case CodecBase::kWhatFillThisBuffer:
1134                {
1135                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
1136
1137                    if (mState == FLUSHING
1138                            || mState == STOPPING
1139                            || mState == RELEASING) {
1140                        returnBuffersToCodecOnPort(kPortIndexInput);
1141                        break;
1142                    }
1143
1144                    if (!mCSD.empty()) {
1145                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
1146                        CHECK_GE(index, 0);
1147
1148                        // If codec specific data had been specified as
1149                        // part of the format in the call to configure and
1150                        // if there's more csd left, we submit it here
1151                        // clients only get access to input buffers once
1152                        // this data has been exhausted.
1153
1154                        status_t err = queueCSDInputBuffer(index);
1155
1156                        if (err != OK) {
1157                            ALOGE("queueCSDInputBuffer failed w/ error %d",
1158                                  err);
1159
1160                            setStickyError(err);
1161                            postActivityNotificationIfPossible();
1162
1163                            cancelPendingDequeueOperations();
1164                        }
1165                        break;
1166                    }
1167
1168                    if (mFlags & kFlagIsAsync) {
1169                        if (!mHaveInputSurface) {
1170                            onInputBufferAvailable();
1171                        }
1172                    } else if (mFlags & kFlagDequeueInputPending) {
1173                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
1174
1175                        ++mDequeueInputTimeoutGeneration;
1176                        mFlags &= ~kFlagDequeueInputPending;
1177                        mDequeueInputReplyID = 0;
1178                    } else {
1179                        postActivityNotificationIfPossible();
1180                    }
1181                    break;
1182                }
1183
1184                case CodecBase::kWhatDrainThisBuffer:
1185                {
1186                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
1187
1188                    if (mState == FLUSHING
1189                            || mState == STOPPING
1190                            || mState == RELEASING) {
1191                        returnBuffersToCodecOnPort(kPortIndexOutput);
1192                        break;
1193                    }
1194
1195                    sp<ABuffer> buffer;
1196                    CHECK(msg->findBuffer("buffer", &buffer));
1197
1198                    int32_t omxFlags;
1199                    CHECK(msg->findInt32("flags", &omxFlags));
1200
1201                    buffer->meta()->setInt32("omxFlags", omxFlags);
1202
1203                    if (mFlags & kFlagGatherCodecSpecificData) {
1204                        // This is the very first output buffer after a
1205                        // format change was signalled, it'll either contain
1206                        // the one piece of codec specific data we can expect
1207                        // or there won't be codec specific data.
1208                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1209                            status_t err =
1210                                amendOutputFormatWithCodecSpecificData(buffer);
1211
1212                            if (err != OK) {
1213                                ALOGE("Codec spit out malformed codec "
1214                                      "specific data!");
1215                            }
1216                        }
1217
1218                        mFlags &= ~kFlagGatherCodecSpecificData;
1219                        if (mFlags & kFlagIsAsync) {
1220                            onOutputFormatChanged();
1221                        } else {
1222                            mFlags |= kFlagOutputFormatChanged;
1223                        }
1224                    }
1225
1226                    if (mFlags & kFlagIsAsync) {
1227                        onOutputBufferAvailable();
1228                    } else if (mFlags & kFlagDequeueOutputPending) {
1229                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
1230
1231                        ++mDequeueOutputTimeoutGeneration;
1232                        mFlags &= ~kFlagDequeueOutputPending;
1233                        mDequeueOutputReplyID = 0;
1234                    } else {
1235                        postActivityNotificationIfPossible();
1236                    }
1237
1238                    break;
1239                }
1240
1241                case CodecBase::kWhatEOS:
1242                {
1243                    // We already notify the client of this by using the
1244                    // corresponding flag in "onOutputBufferReady".
1245                    break;
1246                }
1247
1248                case CodecBase::kWhatShutdownCompleted:
1249                {
1250                    if (mState == STOPPING) {
1251                        setState(INITIALIZED);
1252                    } else {
1253                        CHECK_EQ(mState, RELEASING);
1254                        setState(UNINITIALIZED);
1255                        mComponentName.clear();
1256                    }
1257                    mFlags &= ~kFlagIsComponentAllocated;
1258
1259                    (new AMessage)->postReply(mReplyID);
1260                    break;
1261                }
1262
1263                case CodecBase::kWhatFlushCompleted:
1264                {
1265                    if (mState != FLUSHING) {
1266                        ALOGW("received FlushCompleted message in state %d",
1267                                mState);
1268                        break;
1269                    }
1270
1271                    if (mFlags & kFlagIsAsync) {
1272                        setState(FLUSHED);
1273                    } else {
1274                        setState(STARTED);
1275                        mCodec->signalResume();
1276                    }
1277
1278                    (new AMessage)->postReply(mReplyID);
1279                    break;
1280                }
1281
1282                default:
1283                    TRESPASS();
1284            }
1285            break;
1286        }
1287
1288        case kWhatInit:
1289        {
1290            sp<AReplyToken> replyID;
1291            CHECK(msg->senderAwaitsResponse(&replyID));
1292
1293            if (mState != UNINITIALIZED) {
1294                PostReplyWithError(replyID, INVALID_OPERATION);
1295                break;
1296            }
1297
1298            mReplyID = replyID;
1299            setState(INITIALIZING);
1300
1301            AString name;
1302            CHECK(msg->findString("name", &name));
1303
1304            int32_t nameIsType;
1305            int32_t encoder = false;
1306            CHECK(msg->findInt32("nameIsType", &nameIsType));
1307            if (nameIsType) {
1308                CHECK(msg->findInt32("encoder", &encoder));
1309            }
1310
1311            sp<AMessage> format = new AMessage;
1312
1313            if (nameIsType) {
1314                format->setString("mime", name.c_str());
1315                format->setInt32("encoder", encoder);
1316            } else {
1317                format->setString("componentName", name.c_str());
1318            }
1319
1320            mCodec->initiateAllocateComponent(format);
1321            break;
1322        }
1323
1324        case kWhatSetCallback:
1325        {
1326            sp<AReplyToken> replyID;
1327            CHECK(msg->senderAwaitsResponse(&replyID));
1328
1329            if (mState == UNINITIALIZED
1330                    || mState == INITIALIZING
1331                    || isExecuting()) {
1332                // callback can't be set after codec is executing,
1333                // or before it's initialized (as the callback
1334                // will be cleared when it goes to INITIALIZED)
1335                PostReplyWithError(replyID, INVALID_OPERATION);
1336                break;
1337            }
1338
1339            sp<AMessage> callback;
1340            CHECK(msg->findMessage("callback", &callback));
1341
1342            mCallback = callback;
1343
1344            if (mCallback != NULL) {
1345                ALOGI("MediaCodec will operate in async mode");
1346                mFlags |= kFlagIsAsync;
1347            } else {
1348                mFlags &= ~kFlagIsAsync;
1349            }
1350
1351            sp<AMessage> response = new AMessage;
1352            response->postReply(replyID);
1353            break;
1354        }
1355
1356        case kWhatConfigure:
1357        {
1358            sp<AReplyToken> replyID;
1359            CHECK(msg->senderAwaitsResponse(&replyID));
1360
1361            if (mState != INITIALIZED) {
1362                PostReplyWithError(replyID, INVALID_OPERATION);
1363                break;
1364            }
1365
1366            sp<RefBase> obj;
1367            if (!msg->findObject("native-window", &obj)) {
1368                obj.clear();
1369            }
1370
1371            sp<AMessage> format;
1372            CHECK(msg->findMessage("format", &format));
1373
1374            if (obj != NULL) {
1375                format->setObject("native-window", obj);
1376
1377                status_t err = setNativeWindow(
1378                    static_cast<NativeWindowWrapper *>(obj.get())
1379                        ->getSurfaceTextureClient());
1380
1381                if (err != OK) {
1382                    PostReplyWithError(replyID, err);
1383                    break;
1384                }
1385            } else {
1386                setNativeWindow(NULL);
1387            }
1388
1389            mReplyID = replyID;
1390            setState(CONFIGURING);
1391
1392            void *crypto;
1393            if (!msg->findPointer("crypto", &crypto)) {
1394                crypto = NULL;
1395            }
1396
1397            mCrypto = static_cast<ICrypto *>(crypto);
1398
1399            uint32_t flags;
1400            CHECK(msg->findInt32("flags", (int32_t *)&flags));
1401
1402            if (flags & CONFIGURE_FLAG_ENCODE) {
1403                format->setInt32("encoder", true);
1404                mFlags |= kFlagIsEncoder;
1405            }
1406
1407            extractCSD(format);
1408
1409            mCodec->initiateConfigureComponent(format);
1410            break;
1411        }
1412
1413        case kWhatCreateInputSurface:
1414        {
1415            sp<AReplyToken> replyID;
1416            CHECK(msg->senderAwaitsResponse(&replyID));
1417
1418            // Must be configured, but can't have been started yet.
1419            if (mState != CONFIGURED) {
1420                PostReplyWithError(replyID, INVALID_OPERATION);
1421                break;
1422            }
1423
1424            mReplyID = replyID;
1425            mCodec->initiateCreateInputSurface();
1426            break;
1427        }
1428
1429        case kWhatStart:
1430        {
1431            sp<AReplyToken> replyID;
1432            CHECK(msg->senderAwaitsResponse(&replyID));
1433
1434            if (mState == FLUSHED) {
1435                setState(STARTED);
1436                mCodec->signalResume();
1437                PostReplyWithError(replyID, OK);
1438                break;
1439            } else if (mState != CONFIGURED) {
1440                PostReplyWithError(replyID, INVALID_OPERATION);
1441                break;
1442            }
1443
1444            mReplyID = replyID;
1445            setState(STARTING);
1446
1447            mCodec->initiateStart();
1448            break;
1449        }
1450
1451        case kWhatStop:
1452        case kWhatRelease:
1453        {
1454            State targetState =
1455                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1456
1457            sp<AReplyToken> replyID;
1458            CHECK(msg->senderAwaitsResponse(&replyID));
1459
1460            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
1461                    && mState != INITIALIZED
1462                    && mState != CONFIGURED && !isExecuting()) {
1463                // 1) Permit release to shut down the component if allocated.
1464                //
1465                // 2) We may be in "UNINITIALIZED" state already and
1466                // also shutdown the encoder/decoder without the
1467                // client being aware of this if media server died while
1468                // we were being stopped. The client would assume that
1469                // after stop() returned, it would be safe to call release()
1470                // and it should be in this case, no harm to allow a release()
1471                // if we're already uninitialized.
1472                sp<AMessage> response = new AMessage;
1473                status_t err = mState == targetState ? OK : INVALID_OPERATION;
1474                response->setInt32("err", err);
1475                if (err == OK && targetState == UNINITIALIZED) {
1476                    mComponentName.clear();
1477                }
1478                response->postReply(replyID);
1479                break;
1480            }
1481
1482            if (mFlags & kFlagSawMediaServerDie) {
1483                // It's dead, Jim. Don't expect initiateShutdown to yield
1484                // any useful results now...
1485                setState(UNINITIALIZED);
1486                if (targetState == UNINITIALIZED) {
1487                    mComponentName.clear();
1488                }
1489                (new AMessage)->postReply(replyID);
1490                break;
1491            }
1492
1493            mReplyID = replyID;
1494            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1495
1496            mCodec->initiateShutdown(
1497                    msg->what() == kWhatStop /* keepComponentAllocated */);
1498
1499            returnBuffersToCodec();
1500            break;
1501        }
1502
1503        case kWhatDequeueInputBuffer:
1504        {
1505            sp<AReplyToken> replyID;
1506            CHECK(msg->senderAwaitsResponse(&replyID));
1507
1508            if (mFlags & kFlagIsAsync) {
1509                ALOGE("dequeueOutputBuffer can't be used in async mode");
1510                PostReplyWithError(replyID, INVALID_OPERATION);
1511                break;
1512            }
1513
1514            if (mHaveInputSurface) {
1515                ALOGE("dequeueInputBuffer can't be used with input surface");
1516                PostReplyWithError(replyID, INVALID_OPERATION);
1517                break;
1518            }
1519
1520            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
1521                break;
1522            }
1523
1524            int64_t timeoutUs;
1525            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1526
1527            if (timeoutUs == 0ll) {
1528                PostReplyWithError(replyID, -EAGAIN);
1529                break;
1530            }
1531
1532            mFlags |= kFlagDequeueInputPending;
1533            mDequeueInputReplyID = replyID;
1534
1535            if (timeoutUs > 0ll) {
1536                sp<AMessage> timeoutMsg =
1537                    new AMessage(kWhatDequeueInputTimedOut, this);
1538                timeoutMsg->setInt32(
1539                        "generation", ++mDequeueInputTimeoutGeneration);
1540                timeoutMsg->post(timeoutUs);
1541            }
1542            break;
1543        }
1544
1545        case kWhatDequeueInputTimedOut:
1546        {
1547            int32_t generation;
1548            CHECK(msg->findInt32("generation", &generation));
1549
1550            if (generation != mDequeueInputTimeoutGeneration) {
1551                // Obsolete
1552                break;
1553            }
1554
1555            CHECK(mFlags & kFlagDequeueInputPending);
1556
1557            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
1558
1559            mFlags &= ~kFlagDequeueInputPending;
1560            mDequeueInputReplyID = 0;
1561            break;
1562        }
1563
1564        case kWhatQueueInputBuffer:
1565        {
1566            sp<AReplyToken> replyID;
1567            CHECK(msg->senderAwaitsResponse(&replyID));
1568
1569            if (!isExecuting()) {
1570                PostReplyWithError(replyID, INVALID_OPERATION);
1571                break;
1572            } else if (mFlags & kFlagStickyError) {
1573                PostReplyWithError(replyID, getStickyError());
1574                break;
1575            }
1576
1577            status_t err = onQueueInputBuffer(msg);
1578
1579            PostReplyWithError(replyID, err);
1580            break;
1581        }
1582
1583        case kWhatDequeueOutputBuffer:
1584        {
1585            sp<AReplyToken> replyID;
1586            CHECK(msg->senderAwaitsResponse(&replyID));
1587
1588            if (mFlags & kFlagIsAsync) {
1589                ALOGE("dequeueOutputBuffer can't be used in async mode");
1590                PostReplyWithError(replyID, INVALID_OPERATION);
1591                break;
1592            }
1593
1594            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
1595                break;
1596            }
1597
1598            int64_t timeoutUs;
1599            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1600
1601            if (timeoutUs == 0ll) {
1602                PostReplyWithError(replyID, -EAGAIN);
1603                break;
1604            }
1605
1606            mFlags |= kFlagDequeueOutputPending;
1607            mDequeueOutputReplyID = replyID;
1608
1609            if (timeoutUs > 0ll) {
1610                sp<AMessage> timeoutMsg =
1611                    new AMessage(kWhatDequeueOutputTimedOut, this);
1612                timeoutMsg->setInt32(
1613                        "generation", ++mDequeueOutputTimeoutGeneration);
1614                timeoutMsg->post(timeoutUs);
1615            }
1616            break;
1617        }
1618
1619        case kWhatDequeueOutputTimedOut:
1620        {
1621            int32_t generation;
1622            CHECK(msg->findInt32("generation", &generation));
1623
1624            if (generation != mDequeueOutputTimeoutGeneration) {
1625                // Obsolete
1626                break;
1627            }
1628
1629            CHECK(mFlags & kFlagDequeueOutputPending);
1630
1631            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
1632
1633            mFlags &= ~kFlagDequeueOutputPending;
1634            mDequeueOutputReplyID = 0;
1635            break;
1636        }
1637
1638        case kWhatReleaseOutputBuffer:
1639        {
1640            sp<AReplyToken> replyID;
1641            CHECK(msg->senderAwaitsResponse(&replyID));
1642
1643            if (!isExecuting()) {
1644                PostReplyWithError(replyID, INVALID_OPERATION);
1645                break;
1646            } else if (mFlags & kFlagStickyError) {
1647                PostReplyWithError(replyID, getStickyError());
1648                break;
1649            }
1650
1651            status_t err = onReleaseOutputBuffer(msg);
1652
1653            PostReplyWithError(replyID, err);
1654            break;
1655        }
1656
1657        case kWhatSignalEndOfInputStream:
1658        {
1659            sp<AReplyToken> replyID;
1660            CHECK(msg->senderAwaitsResponse(&replyID));
1661
1662            if (!isExecuting()) {
1663                PostReplyWithError(replyID, INVALID_OPERATION);
1664                break;
1665            } else if (mFlags & kFlagStickyError) {
1666                PostReplyWithError(replyID, getStickyError());
1667                break;
1668            }
1669
1670            mReplyID = replyID;
1671            mCodec->signalEndOfInputStream();
1672            break;
1673        }
1674
1675        case kWhatGetBuffers:
1676        {
1677            sp<AReplyToken> replyID;
1678            CHECK(msg->senderAwaitsResponse(&replyID));
1679            // Unfortunately widevine legacy source requires knowing all of the
1680            // codec input buffers, so we have to provide them even in async mode.
1681            int32_t widevine = 0;
1682            msg->findInt32("widevine", &widevine);
1683
1684            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
1685                PostReplyWithError(replyID, INVALID_OPERATION);
1686                break;
1687            } else if (mFlags & kFlagStickyError) {
1688                PostReplyWithError(replyID, getStickyError());
1689                break;
1690            }
1691
1692            int32_t portIndex;
1693            CHECK(msg->findInt32("portIndex", &portIndex));
1694
1695            Vector<sp<ABuffer> > *dstBuffers;
1696            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
1697
1698            dstBuffers->clear();
1699            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
1700
1701            for (size_t i = 0; i < srcBuffers.size(); ++i) {
1702                const BufferInfo &info = srcBuffers.itemAt(i);
1703
1704                dstBuffers->push_back(
1705                        (portIndex == kPortIndexInput && mCrypto != NULL)
1706                                ? info.mEncryptedData : info.mData);
1707            }
1708
1709            (new AMessage)->postReply(replyID);
1710            break;
1711        }
1712
1713        case kWhatFlush:
1714        {
1715            sp<AReplyToken> replyID;
1716            CHECK(msg->senderAwaitsResponse(&replyID));
1717
1718            if (!isExecuting()) {
1719                PostReplyWithError(replyID, INVALID_OPERATION);
1720                break;
1721            } else if (mFlags & kFlagStickyError) {
1722                PostReplyWithError(replyID, getStickyError());
1723                break;
1724            }
1725
1726            mReplyID = replyID;
1727            // TODO: skip flushing if already FLUSHED
1728            setState(FLUSHING);
1729
1730            mCodec->signalFlush();
1731            returnBuffersToCodec();
1732            break;
1733        }
1734
1735        case kWhatGetInputFormat:
1736        case kWhatGetOutputFormat:
1737        {
1738            sp<AMessage> format =
1739                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1740
1741            sp<AReplyToken> replyID;
1742            CHECK(msg->senderAwaitsResponse(&replyID));
1743
1744            if ((mState != CONFIGURED && mState != STARTING &&
1745                 mState != STARTED && mState != FLUSHING &&
1746                 mState != FLUSHED)
1747                    || format == NULL) {
1748                PostReplyWithError(replyID, INVALID_OPERATION);
1749                break;
1750            } else if (mFlags & kFlagStickyError) {
1751                PostReplyWithError(replyID, getStickyError());
1752                break;
1753            }
1754
1755            sp<AMessage> response = new AMessage;
1756            response->setMessage("format", format);
1757            response->postReply(replyID);
1758            break;
1759        }
1760
1761        case kWhatRequestIDRFrame:
1762        {
1763            mCodec->signalRequestIDRFrame();
1764            break;
1765        }
1766
1767        case kWhatRequestActivityNotification:
1768        {
1769            CHECK(mActivityNotify == NULL);
1770            CHECK(msg->findMessage("notify", &mActivityNotify));
1771
1772            postActivityNotificationIfPossible();
1773            break;
1774        }
1775
1776        case kWhatGetName:
1777        {
1778            sp<AReplyToken> replyID;
1779            CHECK(msg->senderAwaitsResponse(&replyID));
1780
1781            if (mComponentName.empty()) {
1782                PostReplyWithError(replyID, INVALID_OPERATION);
1783                break;
1784            }
1785
1786            sp<AMessage> response = new AMessage;
1787            response->setString("name", mComponentName.c_str());
1788            response->postReply(replyID);
1789            break;
1790        }
1791
1792        case kWhatSetParameters:
1793        {
1794            sp<AReplyToken> replyID;
1795            CHECK(msg->senderAwaitsResponse(&replyID));
1796
1797            sp<AMessage> params;
1798            CHECK(msg->findMessage("params", &params));
1799
1800            status_t err = onSetParameters(params);
1801
1802            PostReplyWithError(replyID, err);
1803            break;
1804        }
1805
1806        default:
1807            TRESPASS();
1808    }
1809}
1810
1811void MediaCodec::extractCSD(const sp<AMessage> &format) {
1812    mCSD.clear();
1813
1814    size_t i = 0;
1815    for (;;) {
1816        sp<ABuffer> csd;
1817        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
1818            break;
1819        }
1820
1821        mCSD.push_back(csd);
1822        ++i;
1823    }
1824
1825    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
1826}
1827
1828status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
1829    CHECK(!mCSD.empty());
1830
1831    const BufferInfo *info =
1832        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
1833
1834    sp<ABuffer> csd = *mCSD.begin();
1835    mCSD.erase(mCSD.begin());
1836
1837    const sp<ABuffer> &codecInputData =
1838        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
1839
1840    if (csd->size() > codecInputData->capacity()) {
1841        return -EINVAL;
1842    }
1843
1844    memcpy(codecInputData->data(), csd->data(), csd->size());
1845
1846    AString errorDetailMsg;
1847
1848    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
1849    msg->setSize("index", bufferIndex);
1850    msg->setSize("offset", 0);
1851    msg->setSize("size", csd->size());
1852    msg->setInt64("timeUs", 0ll);
1853    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
1854    msg->setPointer("errorDetailMsg", &errorDetailMsg);
1855
1856    return onQueueInputBuffer(msg);
1857}
1858
1859void MediaCodec::setState(State newState) {
1860    if (newState == INITIALIZED || newState == UNINITIALIZED) {
1861        delete mSoftRenderer;
1862        mSoftRenderer = NULL;
1863
1864        mCrypto.clear();
1865        setNativeWindow(NULL);
1866
1867        mInputFormat.clear();
1868        mOutputFormat.clear();
1869        mFlags &= ~kFlagOutputFormatChanged;
1870        mFlags &= ~kFlagOutputBuffersChanged;
1871        mFlags &= ~kFlagStickyError;
1872        mFlags &= ~kFlagIsEncoder;
1873        mFlags &= ~kFlagGatherCodecSpecificData;
1874        mFlags &= ~kFlagIsAsync;
1875        mStickyError = OK;
1876
1877        mActivityNotify.clear();
1878        mCallback.clear();
1879    }
1880
1881    if (newState == UNINITIALIZED) {
1882        // return any straggling buffers, e.g. if we got here on an error
1883        returnBuffersToCodec();
1884
1885        // The component is gone, mediaserver's probably back up already
1886        // but should definitely be back up should we try to instantiate
1887        // another component.. and the cycle continues.
1888        mFlags &= ~kFlagSawMediaServerDie;
1889    }
1890
1891    mState = newState;
1892
1893    cancelPendingDequeueOperations();
1894
1895    updateBatteryStat();
1896}
1897
1898void MediaCodec::returnBuffersToCodec() {
1899    returnBuffersToCodecOnPort(kPortIndexInput);
1900    returnBuffersToCodecOnPort(kPortIndexOutput);
1901}
1902
1903void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
1904    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1905    Mutex::Autolock al(mBufferLock);
1906
1907    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1908
1909    for (size_t i = 0; i < buffers->size(); ++i) {
1910        BufferInfo *info = &buffers->editItemAt(i);
1911
1912        if (info->mNotify != NULL) {
1913            sp<AMessage> msg = info->mNotify;
1914            info->mNotify = NULL;
1915            info->mOwnedByClient = false;
1916
1917            if (portIndex == kPortIndexInput) {
1918                /* no error, just returning buffers */
1919                msg->setInt32("err", OK);
1920            }
1921            msg->post();
1922        }
1923    }
1924
1925    mAvailPortBuffers[portIndex].clear();
1926}
1927
1928size_t MediaCodec::updateBuffers(
1929        int32_t portIndex, const sp<AMessage> &msg) {
1930    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1931
1932    uint32_t bufferID;
1933    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
1934
1935    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1936
1937    for (size_t i = 0; i < buffers->size(); ++i) {
1938        BufferInfo *info = &buffers->editItemAt(i);
1939
1940        if (info->mBufferID == bufferID) {
1941            CHECK(info->mNotify == NULL);
1942            CHECK(msg->findMessage("reply", &info->mNotify));
1943
1944            info->mFormat =
1945                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
1946            mAvailPortBuffers[portIndex].push_back(i);
1947
1948            return i;
1949        }
1950    }
1951
1952    TRESPASS();
1953
1954    return 0;
1955}
1956
1957status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
1958    size_t index;
1959    size_t offset;
1960    size_t size;
1961    int64_t timeUs;
1962    uint32_t flags;
1963    CHECK(msg->findSize("index", &index));
1964    CHECK(msg->findSize("offset", &offset));
1965    CHECK(msg->findInt64("timeUs", &timeUs));
1966    CHECK(msg->findInt32("flags", (int32_t *)&flags));
1967
1968    const CryptoPlugin::SubSample *subSamples;
1969    size_t numSubSamples;
1970    const uint8_t *key;
1971    const uint8_t *iv;
1972    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
1973
1974    // We allow the simpler queueInputBuffer API to be used even in
1975    // secure mode, by fabricating a single unencrypted subSample.
1976    CryptoPlugin::SubSample ss;
1977
1978    if (msg->findSize("size", &size)) {
1979        if (mCrypto != NULL) {
1980            ss.mNumBytesOfClearData = size;
1981            ss.mNumBytesOfEncryptedData = 0;
1982
1983            subSamples = &ss;
1984            numSubSamples = 1;
1985            key = NULL;
1986            iv = NULL;
1987        }
1988    } else {
1989        if (mCrypto == NULL) {
1990            return -EINVAL;
1991        }
1992
1993        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
1994        CHECK(msg->findSize("numSubSamples", &numSubSamples));
1995        CHECK(msg->findPointer("key", (void **)&key));
1996        CHECK(msg->findPointer("iv", (void **)&iv));
1997
1998        int32_t tmp;
1999        CHECK(msg->findInt32("mode", &tmp));
2000
2001        mode = (CryptoPlugin::Mode)tmp;
2002
2003        size = 0;
2004        for (size_t i = 0; i < numSubSamples; ++i) {
2005            size += subSamples[i].mNumBytesOfClearData;
2006            size += subSamples[i].mNumBytesOfEncryptedData;
2007        }
2008    }
2009
2010    if (index >= mPortBuffers[kPortIndexInput].size()) {
2011        return -ERANGE;
2012    }
2013
2014    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
2015
2016    if (info->mNotify == NULL || !info->mOwnedByClient) {
2017        return -EACCES;
2018    }
2019
2020    if (offset + size > info->mData->capacity()) {
2021        return -EINVAL;
2022    }
2023
2024    sp<AMessage> reply = info->mNotify;
2025    info->mData->setRange(offset, size);
2026    info->mData->meta()->setInt64("timeUs", timeUs);
2027
2028    if (flags & BUFFER_FLAG_EOS) {
2029        info->mData->meta()->setInt32("eos", true);
2030    }
2031
2032    if (flags & BUFFER_FLAG_CODECCONFIG) {
2033        info->mData->meta()->setInt32("csd", true);
2034    }
2035
2036    if (mCrypto != NULL) {
2037        if (size > info->mEncryptedData->capacity()) {
2038            return -ERANGE;
2039        }
2040
2041        AString *errorDetailMsg;
2042        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
2043
2044        ssize_t result = mCrypto->decrypt(
2045                (mFlags & kFlagIsSecure) != 0,
2046                key,
2047                iv,
2048                mode,
2049                info->mSharedEncryptedBuffer,
2050                offset,
2051                subSamples,
2052                numSubSamples,
2053                info->mData->base(),
2054                errorDetailMsg);
2055
2056        if (result < 0) {
2057            return result;
2058        }
2059
2060        info->mData->setRange(0, result);
2061    }
2062
2063    // synchronization boundary for getBufferAndFormat
2064    {
2065        Mutex::Autolock al(mBufferLock);
2066        info->mOwnedByClient = false;
2067    }
2068    reply->setBuffer("buffer", info->mData);
2069    reply->post();
2070
2071    info->mNotify = NULL;
2072
2073    return OK;
2074}
2075
2076status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
2077    size_t index;
2078    CHECK(msg->findSize("index", &index));
2079
2080    int32_t render;
2081    if (!msg->findInt32("render", &render)) {
2082        render = 0;
2083    }
2084
2085    if (!isExecuting()) {
2086        return -EINVAL;
2087    }
2088
2089    if (index >= mPortBuffers[kPortIndexOutput].size()) {
2090        return -ERANGE;
2091    }
2092
2093    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
2094
2095    if (info->mNotify == NULL || !info->mOwnedByClient) {
2096        return -EACCES;
2097    }
2098
2099    // synchronization boundary for getBufferAndFormat
2100    {
2101        Mutex::Autolock al(mBufferLock);
2102        info->mOwnedByClient = false;
2103    }
2104
2105    if (render && info->mData != NULL && info->mData->size() != 0) {
2106        info->mNotify->setInt32("render", true);
2107
2108        int64_t timestampNs = 0;
2109        if (msg->findInt64("timestampNs", &timestampNs)) {
2110            info->mNotify->setInt64("timestampNs", timestampNs);
2111        } else {
2112            // TODO: it seems like we should use the timestamp
2113            // in the (media)buffer as it potentially came from
2114            // an input surface, but we did not propagate it prior to
2115            // API 20.  Perhaps check for target SDK version.
2116#if 0
2117            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
2118                ALOGV("using buffer PTS of %" PRId64, timestampNs);
2119                timestampNs *= 1000;
2120            }
2121#endif
2122        }
2123
2124        if (mSoftRenderer != NULL) {
2125            mSoftRenderer->render(
2126                    info->mData->data(), info->mData->size(),
2127                    timestampNs, NULL, info->mFormat);
2128        }
2129    }
2130
2131    info->mNotify->post();
2132    info->mNotify = NULL;
2133
2134    return OK;
2135}
2136
2137ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
2138    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
2139
2140    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
2141
2142    if (availBuffers->empty()) {
2143        return -EAGAIN;
2144    }
2145
2146    size_t index = *availBuffers->begin();
2147    availBuffers->erase(availBuffers->begin());
2148
2149    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
2150    CHECK(!info->mOwnedByClient);
2151    {
2152        Mutex::Autolock al(mBufferLock);
2153        info->mOwnedByClient = true;
2154
2155        // set image-data
2156        if (info->mFormat != NULL) {
2157            sp<ABuffer> imageData;
2158            if (info->mFormat->findBuffer("image-data", &imageData)) {
2159                info->mData->meta()->setBuffer("image-data", imageData);
2160            }
2161            int32_t left, top, right, bottom;
2162            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
2163                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
2164            }
2165        }
2166    }
2167
2168    return index;
2169}
2170
2171status_t MediaCodec::setNativeWindow(
2172        const sp<Surface> &surfaceTextureClient) {
2173    status_t err;
2174
2175    if (mNativeWindow != NULL) {
2176        err = native_window_api_disconnect(
2177                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
2178
2179        if (err != OK) {
2180            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
2181                    strerror(-err), err);
2182        }
2183
2184        mNativeWindow.clear();
2185    }
2186
2187    if (surfaceTextureClient != NULL) {
2188        err = native_window_api_connect(
2189                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
2190
2191        if (err != OK) {
2192            ALOGE("native_window_api_connect returned an error: %s (%d)",
2193                    strerror(-err), err);
2194
2195            return err;
2196        }
2197
2198        mNativeWindow = surfaceTextureClient;
2199    }
2200
2201    return OK;
2202}
2203
2204void MediaCodec::onInputBufferAvailable() {
2205    int32_t index;
2206    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2207        sp<AMessage> msg = mCallback->dup();
2208        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2209        msg->setInt32("index", index);
2210        msg->post();
2211    }
2212}
2213
2214void MediaCodec::onOutputBufferAvailable() {
2215    int32_t index;
2216    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2217        const sp<ABuffer> &buffer =
2218            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2219        sp<AMessage> msg = mCallback->dup();
2220        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2221        msg->setInt32("index", index);
2222        msg->setSize("offset", buffer->offset());
2223        msg->setSize("size", buffer->size());
2224
2225        int64_t timeUs;
2226        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2227
2228        msg->setInt64("timeUs", timeUs);
2229
2230        int32_t omxFlags;
2231        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2232
2233        uint32_t flags = 0;
2234        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2235            flags |= BUFFER_FLAG_SYNCFRAME;
2236        }
2237        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2238            flags |= BUFFER_FLAG_CODECCONFIG;
2239        }
2240        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2241            flags |= BUFFER_FLAG_EOS;
2242        }
2243
2244        msg->setInt32("flags", flags);
2245
2246        msg->post();
2247    }
2248}
2249
2250void MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2251    if (mCallback != NULL) {
2252        sp<AMessage> msg = mCallback->dup();
2253        msg->setInt32("callbackID", CB_ERROR);
2254        msg->setInt32("err", err);
2255        msg->setInt32("actionCode", actionCode);
2256
2257        if (detail != NULL) {
2258            msg->setString("detail", detail);
2259        }
2260
2261        msg->post();
2262    }
2263}
2264
2265void MediaCodec::onOutputFormatChanged() {
2266    if (mCallback != NULL) {
2267        sp<AMessage> msg = mCallback->dup();
2268        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2269        msg->setMessage("format", mOutputFormat);
2270        msg->post();
2271    }
2272}
2273
2274
2275void MediaCodec::postActivityNotificationIfPossible() {
2276    if (mActivityNotify == NULL) {
2277        return;
2278    }
2279
2280    bool isErrorOrOutputChanged =
2281            (mFlags & (kFlagStickyError
2282                    | kFlagOutputBuffersChanged
2283                    | kFlagOutputFormatChanged));
2284
2285    if (isErrorOrOutputChanged
2286            || !mAvailPortBuffers[kPortIndexInput].empty()
2287            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2288        mActivityNotify->setInt32("input-buffers",
2289                mAvailPortBuffers[kPortIndexInput].size());
2290
2291        if (isErrorOrOutputChanged) {
2292            // we want consumer to dequeue as many times as it can
2293            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2294        } else {
2295            mActivityNotify->setInt32("output-buffers",
2296                    mAvailPortBuffers[kPortIndexOutput].size());
2297        }
2298        mActivityNotify->post();
2299        mActivityNotify.clear();
2300    }
2301}
2302
2303status_t MediaCodec::setParameters(const sp<AMessage> &params) {
2304    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2305    msg->setMessage("params", params);
2306
2307    sp<AMessage> response;
2308    return PostAndAwaitResponse(msg, &response);
2309}
2310
2311status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2312    mCodec->signalSetParameters(params);
2313
2314    return OK;
2315}
2316
2317status_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2318        const sp<ABuffer> &buffer) {
2319    AString mime;
2320    CHECK(mOutputFormat->findString("mime", &mime));
2321
2322    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2323        // Codec specific data should be SPS and PPS in a single buffer,
2324        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2325        // We separate the two and put them into the output format
2326        // under the keys "csd-0" and "csd-1".
2327
2328        unsigned csdIndex = 0;
2329
2330        const uint8_t *data = buffer->data();
2331        size_t size = buffer->size();
2332
2333        const uint8_t *nalStart;
2334        size_t nalSize;
2335        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2336            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2337            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2338            memcpy(csd->data() + 4, nalStart, nalSize);
2339
2340            mOutputFormat->setBuffer(
2341                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2342
2343            ++csdIndex;
2344        }
2345
2346        if (csdIndex != 2) {
2347            return ERROR_MALFORMED;
2348        }
2349    } else {
2350        // For everything else we just stash the codec specific data into
2351        // the output format as a single piece of csd under "csd-0".
2352        mOutputFormat->setBuffer("csd-0", buffer);
2353    }
2354
2355    return OK;
2356}
2357
2358void MediaCodec::updateBatteryStat() {
2359    if (mState == CONFIGURED && !mBatteryStatNotified) {
2360        AString mime;
2361        CHECK(mOutputFormat != NULL &&
2362                mOutputFormat->findString("mime", &mime));
2363
2364        mIsVideo = mime.startsWithIgnoreCase("video/");
2365
2366        BatteryNotifier& notifier(BatteryNotifier::getInstance());
2367
2368        if (mIsVideo) {
2369            notifier.noteStartVideo();
2370        } else {
2371            notifier.noteStartAudio();
2372        }
2373
2374        mBatteryStatNotified = true;
2375    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
2376        BatteryNotifier& notifier(BatteryNotifier::getInstance());
2377
2378        if (mIsVideo) {
2379            notifier.noteStopVideo();
2380        } else {
2381            notifier.noteStopAudio();
2382        }
2383
2384        mBatteryStatNotified = false;
2385    }
2386}
2387
2388}  // namespace android
2389