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