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