MediaCodec.cpp revision 575a5361fc970476cd7979638ee3ac00cc6e5024
1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/*
2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright 2012, The Android Open Source Project
3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License");
5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License.
6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at
7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *     http://www.apache.org/licenses/LICENSE-2.0
9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat *
10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software
11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS,
12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and
14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License.
15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */
16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat//#define LOG_NDEBUG 0
18fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#define LOG_TAG "MediaCodec"
19fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <utils/Log.h>
20f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
21a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/stagefright/MediaCodec.h>
22a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
23a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include "include/SoftwareRenderer.h"
24a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
25a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <gui/SurfaceTextureClient.h>
26a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <media/ICrypto.h>
27f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/ABuffer.h>
28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/ADebug.h>
29f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/AMessage.h>
30f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/AString.h>
31f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/foundation/hexdump.h>
32fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <media/stagefright/ACodec.h>
33fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <media/stagefright/MediaErrors.h>
34f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <media/stagefright/MetaData.h>
35ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat#include <media/stagefright/NativeWindowWrapper.h>
36a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
37a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatnamespace android {
38a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
39b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat// static
40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatsp<MediaCodec> MediaCodec::CreateByType(
4123969931fad6e993832208f099f6eea0f6f76eb5San Mehat        const sp<ALooper> &looper, const char *mime, bool encoder) {
4223969931fad6e993832208f099f6eea0f6f76eb5San Mehat    sp<MediaCodec> codec = new MediaCodec(looper);
43f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    if (codec->init(mime, true /* nameIsType */, encoder) != OK) {
44f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        return NULL;
45f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    }
46f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
47f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    return codec;
48f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
49f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat// static
51f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatsp<MediaCodec> MediaCodec::CreateByComponentName(
52f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        const sp<ALooper> &looper, const char *name) {
53f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    sp<MediaCodec> codec = new MediaCodec(looper);
54f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) {
55a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        return NULL;
56f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    }
57f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
58f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    return codec;
59f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
60f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
61f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatMediaCodec::MediaCodec(const sp<ALooper> &looper)
62f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    : mState(UNINITIALIZED),
63f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat      mLooper(looper),
64f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat      mCodec(new ACodec),
65f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat      mFlags(0),
66f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat      mSoftRenderer(NULL),
67f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat      mDequeueInputTimeoutGeneration(0),
68f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat      mDequeueInputReplyID(0),
69f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat      mDequeueOutputTimeoutGeneration(0),
70f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat      mDequeueOutputReplyID(0) {
71f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat}
72f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
73f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatMediaCodec::~MediaCodec() {
74f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    CHECK_EQ(mState, UNINITIALIZED);
75a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
76a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
77a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat// static
78a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatus_t MediaCodec::PostAndAwaitResponse(
79a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        const sp<AMessage> &msg, sp<AMessage> *response) {
80a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    status_t err = msg->postAndAwaitResponse(response);
81a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
82a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (err != OK) {
83a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        return err;
84a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
85a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
86a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (!(*response)->findInt32("err", &err)) {
87a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        err = OK;
88a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
89a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
90a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    return err;
910cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat}
92a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
93a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatus_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
94a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    // Current video decoders do not return from OMX_FillThisBuffer
950cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat    // quickly, violating the OpenMAX specs, until that is remedied
960cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat    // we need to invest in an extra looper to free the main event
970cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat    // queue.
980cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat    bool needDedicatedLooper = false;
990cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat    if (nameIsType && !strncasecmp(name, "video/", 6)) {
100a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        needDedicatedLooper = true;
101a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    } else if (!nameIsType && !strncmp(name, "OMX.TI.DUCATI1.VIDEO.", 21)) {
102a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        needDedicatedLooper = true;
103a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
104a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
105a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (needDedicatedLooper) {
106a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        if (mCodecLooper == NULL) {
107a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            mCodecLooper = new ALooper;
108a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            mCodecLooper->setName("CodecLooper");
109a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
110a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        }
111a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
112fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat        mCodecLooper->registerHandler(mCodec);
113fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    } else {
114f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        mLooper->registerHandler(mCodec);
115fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    }
116f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
117f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    mLooper->registerHandler(this);
118f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
119fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
120a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
121a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    sp<AMessage> msg = new AMessage(kWhatInit, id());
122a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    msg->setString("name", name);
123f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    msg->setInt32("nameIsType", nameIsType);
124f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
125f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    if (nameIsType) {
126f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        msg->setInt32("encoder", encoder);
127f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    }
128f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
129a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    sp<AMessage> response;
130fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat    return PostAndAwaitResponse(msg, &response);
131a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
132f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
133f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatus_t MediaCodec::configure(
134f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        const sp<AMessage> &format,
135f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        const sp<SurfaceTextureClient> &nativeWindow,
136f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        const sp<ICrypto> &crypto,
137f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        uint32_t flags) {
138f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
139f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
140f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    msg->setMessage("format", format);
141f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    msg->setInt32("flags", flags);
142f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
143a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    if (nativeWindow != NULL) {
144f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat        msg->setObject(
145f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat                "native-window",
146a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                new NativeWindowWrapper(nativeWindow));
147f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat    }
148f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat
14949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat    if (crypto != NULL) {
150a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        msg->setPointer("crypto", crypto.get());
151a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    }
152a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
153a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    sp<AMessage> response;
154a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    return PostAndAwaitResponse(msg, &response);
155a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat}
156a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
157a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatstatus_t MediaCodec::start() {
158a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    sp<AMessage> msg = new AMessage(kWhatStart, id());
159a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
160a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat    sp<AMessage> response;
161a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return PostAndAwaitResponse(msg, &response);
162a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
163a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
164a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::stop() {
165a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> msg = new AMessage(kWhatStop, id());
166a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
167a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> response;
168a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return PostAndAwaitResponse(msg, &response);
169a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
170a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
171a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::release() {
172a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> msg = new AMessage(kWhatRelease, id());
173a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
174a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> response;
175a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return PostAndAwaitResponse(msg, &response);
176a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
177a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
178a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::queueInputBuffer(
179a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        size_t index,
180a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        size_t offset,
181a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        size_t size,
182a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        int64_t presentationTimeUs,
183a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        uint32_t flags,
184a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        AString *errorDetailMsg) {
185a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    if (errorDetailMsg != NULL) {
186a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        errorDetailMsg->clear();
187a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
188a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
189a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
190a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setSize("index", index);
191a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setSize("offset", offset);
192a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setSize("size", size);
193a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setInt64("timeUs", presentationTimeUs);
194a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setInt32("flags", flags);
195a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setPointer("errorDetailMsg", errorDetailMsg);
196a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
197a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> response;
198a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return PostAndAwaitResponse(msg, &response);
199a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
200a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
201a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::queueSecureInputBuffer(
2028da6bcb006f4e4257cdd685e35e910a6334f6ceaSan Mehat        size_t index,
203a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        size_t offset,
204a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        const CryptoPlugin::SubSample *subSamples,
205a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        size_t numSubSamples,
206a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        const uint8_t key[16],
207a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        const uint8_t iv[16],
208b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        CryptoPlugin::Mode mode,
209b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        int64_t presentationTimeUs,
210a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        uint32_t flags,
211b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        AString *errorDetailMsg) {
212b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    if (errorDetailMsg != NULL) {
213b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        errorDetailMsg->clear();
214b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    }
215b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
216b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
217b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setSize("index", index);
218b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setSize("offset", offset);
219b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setPointer("subSamples", (void *)subSamples);
220b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setSize("numSubSamples", numSubSamples);
221b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setPointer("key", (void *)key);
222b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setPointer("iv", (void *)iv);
223b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setInt32("mode", mode);
224b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setInt64("timeUs", presentationTimeUs);
225a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setInt32("flags", flags);
226b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setPointer("errorDetailMsg", errorDetailMsg);
227b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
228b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> response;
229a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    status_t err = PostAndAwaitResponse(msg, &response);
230a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
231a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return err;
232a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
233a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
234a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
235a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
236a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setInt64("timeoutUs", timeoutUs);
237a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
238eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat    sp<AMessage> response;
239eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat    status_t err;
240b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
241b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        return err;
242b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    }
243eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat
244eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat    CHECK(response->findSize("index", index));
245eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat
246eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat    return OK;
247a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
248a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
249b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatstatus_t MediaCodec::dequeueOutputBuffer(
250cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat        size_t *index,
251cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat        size_t *offset,
252a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        size_t *size,
253b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        int64_t *presentationTimeUs,
254b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        uint32_t *flags,
255b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        int64_t timeoutUs) {
256a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
257a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setInt64("timeoutUs", timeoutUs);
258a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
259a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> response;
260a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    status_t err;
261a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
262a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        return err;
263a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
264a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
265a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    CHECK(response->findSize("index", index));
266a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    CHECK(response->findSize("offset", offset));
267a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    CHECK(response->findSize("size", size));
268a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    CHECK(response->findInt64("timeUs", presentationTimeUs));
269a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    CHECK(response->findInt32("flags", (int32_t *)flags));
270a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
271a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return OK;
272a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
273a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
274a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
275a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
276a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setSize("index", index);
277a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setInt32("render", true);
278fff0b47998a722d57eea6a07350bbd7a6032b3ccSan Mehat
279fff0b47998a722d57eea6a07350bbd7a6032b3ccSan Mehat    sp<AMessage> response;
280a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return PostAndAwaitResponse(msg, &response);
281a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
282a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
283a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
284a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
285a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setSize("index", index);
286a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
287a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> response;
288b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    return PostAndAwaitResponse(msg, &response);
289a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
290a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
291a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
292a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
293a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
294a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    sp<AMessage> response;
295a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    status_t err;
296a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
297b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        return err;
298b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    }
299b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
300b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    CHECK(response->findMessage("format", format));
30123969931fad6e993832208f099f6eea0f6f76eb5San Mehat
302b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    return OK;
303b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat}
304b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
305b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
306b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
307a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    msg->setInt32("portIndex", kPortIndexInput);
308b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setPointer("buffers", buffers);
309b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
310b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> response;
311a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return PostAndAwaitResponse(msg, &response);
312b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat}
313b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
314b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
315b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
316b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setInt32("portIndex", kPortIndexOutput);
317b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setPointer("buffers", buffers);
318b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
319b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> response;
320b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    return PostAndAwaitResponse(msg, &response);
321b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat}
322b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
323b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatstatus_t MediaCodec::flush() {
324b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> msg = new AMessage(kWhatFlush, id());
325b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
326b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> response;
327b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    return PostAndAwaitResponse(msg, &response);
328b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat}
329a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
330a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatstatus_t MediaCodec::requestIDRFrame() {
331a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    (new AMessage(kWhatRequestIDRFrame, id()))->post();
332a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
333a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    return OK;
334a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
335b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
336b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatvoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
337b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
338b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->setMessage("notify", notify);
339b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    msg->post();
340b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat}
341b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
342b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat////////////////////////////////////////////////////////////////////////////////
343b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
344b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatvoid MediaCodec::cancelPendingDequeueOperations() {
345b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    if (mFlags & kFlagDequeueInputPending) {
346b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        sp<AMessage> response = new AMessage;
347b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        response->setInt32("err", INVALID_OPERATION);
348a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        response->postReply(mDequeueInputReplyID);
349a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
350a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        ++mDequeueInputTimeoutGeneration;
351a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        mDequeueInputReplyID = 0;
352a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        mFlags &= ~kFlagDequeueInputPending;
353a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
354a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
355a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    if (mFlags & kFlagDequeueOutputPending) {
356a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        sp<AMessage> response = new AMessage;
357a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        response->setInt32("err", INVALID_OPERATION);
358a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        response->postReply(mDequeueOutputReplyID);
359a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
360a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        ++mDequeueOutputTimeoutGeneration;
361a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        mDequeueOutputReplyID = 0;
362a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        mFlags &= ~kFlagDequeueOutputPending;
363a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
364a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat}
365a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
366a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatbool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
367a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    if (mState != STARTED
368a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat            || (mFlags & kFlagStickyError)
369a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
370a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        sp<AMessage> response = new AMessage;
3718da6bcb006f4e4257cdd685e35e910a6334f6ceaSan Mehat        response->setInt32("err", INVALID_OPERATION);
372a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
373a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        response->postReply(replyID);
374a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
375b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        return true;
376b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    }
377b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
378b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    ssize_t index = dequeuePortBuffer(kPortIndexInput);
379b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
380b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    if (index < 0) {
381b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        CHECK_EQ(index, -EAGAIN);
382b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        return false;
383b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    }
384b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
385b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> response = new AMessage;
386b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    response->setSize("index", index);
387b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    response->postReply(replyID);
388b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
389b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    return true;
390b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat}
391b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
392b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatbool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
393b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    sp<AMessage> response = new AMessage;
394b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
395b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    if (mState != STARTED
396b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat            || (mFlags & kFlagStickyError)
397b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
398b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        response->setInt32("err", INVALID_OPERATION);
399b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    } else if (mFlags & kFlagOutputBuffersChanged) {
400b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
401b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        mFlags &= ~kFlagOutputBuffersChanged;
402b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    } else if (mFlags & kFlagOutputFormatChanged) {
403b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        response->setInt32("err", INFO_FORMAT_CHANGED);
404b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        mFlags &= ~kFlagOutputFormatChanged;
405b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat    } else {
406b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
407b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
408b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        if (index < 0) {
409b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat            CHECK_EQ(index, -EAGAIN);
410b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat            return false;
411b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        }
412b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
413b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        const sp<ABuffer> &buffer =
414a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
415a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
416a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        response->setSize("index", index);
417b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        response->setSize("offset", buffer->offset());
418b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        response->setSize("size", buffer->size());
419b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
420b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        int64_t timeUs;
421b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
422b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
423b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        response->setInt64("timeUs", timeUs);
424b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
425a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        int32_t omxFlags;
426a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
427b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat
428cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat        uint32_t flags = 0;
429cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
430a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat            flags |= BUFFER_FLAG_SYNCFRAME;
431b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        }
432b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
433b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat            flags |= BUFFER_FLAG_CODECCONFIG;
434b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat        }
435a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        if (omxFlags & OMX_BUFFERFLAG_EOS) {
436a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat            flags |= BUFFER_FLAG_EOS;
437a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        }
438a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
439a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat        response->setInt32("flags", flags);
440a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat    }
441a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
44249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat    response->postReply(replyID);
44349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
44449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat    return true;
44549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat}
44649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
44749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehatvoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
44849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat    switch (msg->what()) {
44949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat        case kWhatCodecNotify:
450a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat        {
451a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            int32_t what;
452a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            CHECK(msg->findInt32("what", &what));
453a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
454a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat            switch (what) {
455a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                case ACodec::kWhatError:
456a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                {
457a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    int32_t omxError, internalError;
458a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    CHECK(msg->findInt32("omx-error", &omxError));
459a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    CHECK(msg->findInt32("err", &internalError));
460a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
461a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    ALOGE("Codec reported an error. "
462a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                          "(omx error 0x%08x, internalError %d)",
463a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                          omxError, internalError);
464a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
465a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    bool sendErrorReponse = true;
466a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
467a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    switch (mState) {
468a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        case INITIALIZING:
469a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        {
470a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            setState(UNINITIALIZED);
471a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            break;
472a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        }
473a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
474a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        case CONFIGURING:
475a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        {
476a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            setState(INITIALIZED);
477a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            break;
478a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        }
479a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
480a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        case STARTING:
481a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        {
482a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            setState(CONFIGURED);
483a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            break;
484a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        }
485a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
486a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        case STOPPING:
487a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        case RELEASING:
488a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        {
489a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            // Ignore the error, assuming we'll still get
490a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            // the shutdown complete notification.
491a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
492a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            sendErrorReponse = false;
493a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            break;
494a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        }
495a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
496a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        case FLUSHING:
497a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        {
498a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            setState(STARTED);
499a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            break;
500a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        }
501a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
502a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        case STARTED:
503a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        {
504a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            sendErrorReponse = false;
505a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
506a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            mFlags |= kFlagStickyError;
507a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            postActivityNotificationIfPossible();
50849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
509a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            cancelPendingDequeueOperations();
51049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                            break;
51149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        }
51249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
51349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        default:
514a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        {
515a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            sendErrorReponse = false;
516a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
517a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            mFlags |= kFlagStickyError;
518a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            postActivityNotificationIfPossible();
519a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            break;
520a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        }
521a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    }
522a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
523a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    if (sendErrorReponse) {
524a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        sp<AMessage> response = new AMessage;
525a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        response->setInt32("err", UNKNOWN_ERROR);
526a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
5270cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat                        response->postReply(mReplyID);
5280cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat                    }
529a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    break;
530a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                }
531a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
532a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                case ACodec::kWhatComponentAllocated:
533a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                {
534a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    CHECK_EQ(mState, INITIALIZING);
535a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    setState(INITIALIZED);
536a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
537a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    AString componentName;
538a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    CHECK(msg->findString("componentName", &componentName));
539a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
540a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    if (componentName.startsWith("OMX.google.")) {
541a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        mFlags |= kFlagIsSoftwareCodec;
542a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    } else {
543a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        mFlags &= ~kFlagIsSoftwareCodec;
544a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    }
545a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
546a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    if (componentName.endsWith(".secure")) {
547a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        mFlags |= kFlagIsSecure;
548a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    } else {
549a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        mFlags &= ~kFlagIsSecure;
550a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    }
551a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
552a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    (new AMessage)->postReply(mReplyID);
553a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    break;
554a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                }
555a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
556a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                case ACodec::kWhatComponentConfigured:
557a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                {
558a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    CHECK_EQ(mState, CONFIGURING);
559a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    setState(CONFIGURED);
560a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
561a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    (new AMessage)->postReply(mReplyID);
562a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    break;
563a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                }
564a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
565a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                case ACodec::kWhatBuffersAllocated:
566a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                {
567a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    int32_t portIndex;
568a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    CHECK(msg->findInt32("portIndex", &portIndex));
569a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
5700cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat                    ALOGV("%s buffers allocated",
571a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                          portIndex == kPortIndexInput ? "input" : "output");
572a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
573a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    CHECK(portIndex == kPortIndexInput
574a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            || portIndex == kPortIndexOutput);
575a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
576a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    mPortBuffers[portIndex].clear();
577a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
578a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
579a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
580a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    sp<RefBase> obj;
581a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    CHECK(msg->findObject("portDesc", &obj));
582a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
583a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    sp<ACodec::PortDescription> portDesc =
584a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        static_cast<ACodec::PortDescription *>(obj.get());
58549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
58649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                    size_t numBuffers = portDesc->countBuffers();
58749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
58849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                    for (size_t i = 0; i < numBuffers; ++i) {
58949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        BufferInfo info;
59049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        info.mBufferID = portDesc->bufferIDAt(i);
59149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        info.mOwnedByClient = false;
59249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        info.mData = portDesc->bufferAt(i);
59349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
59449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
595a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            info.mEncryptedData =
596a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                                new ABuffer(info.mData->capacity());
597a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        }
598a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
599a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        buffers->push_back(info);
60049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                    }
601a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
602a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    if (portIndex == kPortIndexOutput) {
60349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        if (mState == STARTING) {
60449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                            // We're always allocating output buffers after
60549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                            // allocating input buffers, so this is a good
60649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                            // indication that now all buffers are allocated.
607a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            setState(STARTED);
60849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                            (new AMessage)->postReply(mReplyID);
60949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        } else {
610a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            mFlags |= kFlagOutputBuffersChanged;
611a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            postActivityNotificationIfPossible();
612a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        }
61349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                    }
61449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                    break;
61549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                }
61649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
617a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                case ACodec::kWhatOutputFormatChanged:
618a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                {
619a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    ALOGV("codec output format changed");
620a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat
621a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                    if ((mFlags & kFlagIsSoftwareCodec)
622a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                            && mNativeWindow != NULL) {
623a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat                        AString mime;
62449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        CHECK(msg->findString("mime", &mime));
62549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat
62649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat                        if (!strncasecmp("video/", mime.c_str(), 6)) {
627a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            delete mSoftRenderer;
628a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            mSoftRenderer = NULL;
629a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
630a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            int32_t width, height;
631a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            CHECK(msg->findInt32("width", &width));
632a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            CHECK(msg->findInt32("height", &height));
633a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
634a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            int32_t colorFormat;
635a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            CHECK(msg->findInt32(
636a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                                        "color-format", &colorFormat));
637a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
638a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            sp<MetaData> meta = new MetaData;
639a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            meta->setInt32(kKeyWidth, width);
640a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            meta->setInt32(kKeyHeight, height);
641a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            meta->setInt32(kKeyColorFormat, colorFormat);
642a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
643a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                            mSoftRenderer =
644a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                                new SoftwareRenderer(mNativeWindow, meta);
645a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                        }
646a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                    }
647a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
648a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                    mOutputFormat = msg;
649a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                    mFlags |= kFlagOutputFormatChanged;
650a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                    postActivityNotificationIfPossible();
651a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                    break;
652a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                }
653a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat
654a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat                case ACodec::kWhatFillThisBuffer:
655                {
656                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
657
658                    if (mState == FLUSHING
659                            || mState == STOPPING
660                            || mState == RELEASING) {
661                        returnBuffersToCodecOnPort(kPortIndexInput);
662                        break;
663                    }
664
665                    if (!mCSD.empty()) {
666                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
667                        CHECK_GE(index, 0);
668
669                        // If codec specific data had been specified as
670                        // part of the format in the call to configure and
671                        // if there's more csd left, we submit it here
672                        // clients only get access to input buffers once
673                        // this data has been exhausted.
674
675                        status_t err = queueCSDInputBuffer(index);
676
677                        if (err != OK) {
678                            ALOGE("queueCSDInputBuffer failed w/ error %d",
679                                  err);
680
681                            mFlags |= kFlagStickyError;
682                            postActivityNotificationIfPossible();
683
684                            cancelPendingDequeueOperations();
685                        }
686                        break;
687                    }
688
689                    if (mFlags & kFlagDequeueInputPending) {
690                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
691
692                        ++mDequeueInputTimeoutGeneration;
693                        mFlags &= ~kFlagDequeueInputPending;
694                        mDequeueInputReplyID = 0;
695                    } else {
696                        postActivityNotificationIfPossible();
697                    }
698                    break;
699                }
700
701                case ACodec::kWhatDrainThisBuffer:
702                {
703                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
704
705                    if (mState == FLUSHING
706                            || mState == STOPPING
707                            || mState == RELEASING) {
708                        returnBuffersToCodecOnPort(kPortIndexOutput);
709                        break;
710                    }
711
712                    sp<ABuffer> buffer;
713                    CHECK(msg->findBuffer("buffer", &buffer));
714
715                    int32_t omxFlags;
716                    CHECK(msg->findInt32("flags", &omxFlags));
717
718                    buffer->meta()->setInt32("omxFlags", omxFlags);
719
720                    if (mFlags & kFlagDequeueOutputPending) {
721                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
722
723                        ++mDequeueOutputTimeoutGeneration;
724                        mFlags &= ~kFlagDequeueOutputPending;
725                        mDequeueOutputReplyID = 0;
726                    } else {
727                        postActivityNotificationIfPossible();
728                    }
729
730                    break;
731                }
732
733                case ACodec::kWhatEOS:
734                {
735                    // We already notify the client of this by using the
736                    // corresponding flag in "onOutputBufferReady".
737                    break;
738                }
739
740                case ACodec::kWhatShutdownCompleted:
741                {
742                    if (mState == STOPPING) {
743                        setState(INITIALIZED);
744                    } else {
745                        CHECK_EQ(mState, RELEASING);
746                        setState(UNINITIALIZED);
747                    }
748
749                    (new AMessage)->postReply(mReplyID);
750                    break;
751                }
752
753                case ACodec::kWhatFlushCompleted:
754                {
755                    CHECK_EQ(mState, FLUSHING);
756                    setState(STARTED);
757
758                    mCodec->signalResume();
759
760                    (new AMessage)->postReply(mReplyID);
761                    break;
762                }
763
764                default:
765                    TRESPASS();
766            }
767            break;
768        }
769
770        case kWhatInit:
771        {
772            uint32_t replyID;
773            CHECK(msg->senderAwaitsResponse(&replyID));
774
775            if (mState != UNINITIALIZED) {
776                sp<AMessage> response = new AMessage;
777                response->setInt32("err", INVALID_OPERATION);
778
779                response->postReply(replyID);
780                break;
781            }
782
783            mReplyID = replyID;
784            setState(INITIALIZING);
785
786            AString name;
787            CHECK(msg->findString("name", &name));
788
789            int32_t nameIsType;
790            int32_t encoder = false;
791            CHECK(msg->findInt32("nameIsType", &nameIsType));
792            if (nameIsType) {
793                CHECK(msg->findInt32("encoder", &encoder));
794            }
795
796            sp<AMessage> format = new AMessage;
797
798            if (nameIsType) {
799                format->setString("mime", name.c_str());
800                format->setInt32("encoder", encoder);
801            } else {
802                format->setString("componentName", name.c_str());
803            }
804
805            mCodec->initiateAllocateComponent(format);
806            break;
807        }
808
809        case kWhatConfigure:
810        {
811            uint32_t replyID;
812            CHECK(msg->senderAwaitsResponse(&replyID));
813
814            if (mState != INITIALIZED) {
815                sp<AMessage> response = new AMessage;
816                response->setInt32("err", INVALID_OPERATION);
817
818                response->postReply(replyID);
819                break;
820            }
821
822            sp<RefBase> obj;
823            if (!msg->findObject("native-window", &obj)) {
824                obj.clear();
825            }
826
827            sp<AMessage> format;
828            CHECK(msg->findMessage("format", &format));
829
830            if (obj != NULL) {
831                format->setObject("native-window", obj);
832
833                status_t err = setNativeWindow(
834                    static_cast<NativeWindowWrapper *>(obj.get())
835                        ->getSurfaceTextureClient());
836
837                if (err != OK) {
838                    sp<AMessage> response = new AMessage;
839                    response->setInt32("err", err);
840
841                    response->postReply(replyID);
842                    break;
843                }
844            } else {
845                setNativeWindow(NULL);
846            }
847
848            mReplyID = replyID;
849            setState(CONFIGURING);
850
851            void *crypto;
852            if (!msg->findPointer("crypto", &crypto)) {
853                crypto = NULL;
854            }
855
856            mCrypto = static_cast<ICrypto *>(crypto);
857
858            uint32_t flags;
859            CHECK(msg->findInt32("flags", (int32_t *)&flags));
860
861            if (flags & CONFIGURE_FLAG_ENCODE) {
862                format->setInt32("encoder", true);
863            }
864
865            extractCSD(format);
866
867            mCodec->initiateConfigureComponent(format);
868            break;
869        }
870
871        case kWhatStart:
872        {
873            uint32_t replyID;
874            CHECK(msg->senderAwaitsResponse(&replyID));
875
876            if (mState != CONFIGURED) {
877                sp<AMessage> response = new AMessage;
878                response->setInt32("err", INVALID_OPERATION);
879
880                response->postReply(replyID);
881                break;
882            }
883
884            mReplyID = replyID;
885            setState(STARTING);
886
887            mCodec->initiateStart();
888            break;
889        }
890
891        case kWhatStop:
892        {
893            uint32_t replyID;
894            CHECK(msg->senderAwaitsResponse(&replyID));
895
896            if (mState != INITIALIZED
897                    && mState != CONFIGURED && mState != STARTED) {
898                sp<AMessage> response = new AMessage;
899                response->setInt32("err", INVALID_OPERATION);
900
901                response->postReply(replyID);
902                break;
903            }
904
905            mReplyID = replyID;
906            setState(STOPPING);
907
908            mCodec->initiateShutdown(true /* keepComponentAllocated */);
909            returnBuffersToCodec();
910            break;
911        }
912
913        case kWhatRelease:
914        {
915            uint32_t replyID;
916            CHECK(msg->senderAwaitsResponse(&replyID));
917
918            if (mState != INITIALIZED
919                    && mState != CONFIGURED && mState != STARTED) {
920                sp<AMessage> response = new AMessage;
921                response->setInt32("err", INVALID_OPERATION);
922
923                response->postReply(replyID);
924                break;
925            }
926
927            mReplyID = replyID;
928            setState(RELEASING);
929
930            mCodec->initiateShutdown();
931            returnBuffersToCodec();
932            break;
933        }
934
935        case kWhatDequeueInputBuffer:
936        {
937            uint32_t replyID;
938            CHECK(msg->senderAwaitsResponse(&replyID));
939
940            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
941                break;
942            }
943
944            int64_t timeoutUs;
945            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
946
947            if (timeoutUs == 0ll) {
948                sp<AMessage> response = new AMessage;
949                response->setInt32("err", -EAGAIN);
950                response->postReply(replyID);
951                break;
952            }
953
954            mFlags |= kFlagDequeueInputPending;
955            mDequeueInputReplyID = replyID;
956
957            if (timeoutUs > 0ll) {
958                sp<AMessage> timeoutMsg =
959                    new AMessage(kWhatDequeueInputTimedOut, id());
960                timeoutMsg->setInt32(
961                        "generation", ++mDequeueInputTimeoutGeneration);
962                timeoutMsg->post(timeoutUs);
963            }
964            break;
965        }
966
967        case kWhatDequeueInputTimedOut:
968        {
969            int32_t generation;
970            CHECK(msg->findInt32("generation", &generation));
971
972            if (generation != mDequeueInputTimeoutGeneration) {
973                // Obsolete
974                break;
975            }
976
977            CHECK(mFlags & kFlagDequeueInputPending);
978
979            sp<AMessage> response = new AMessage;
980            response->setInt32("err", -EAGAIN);
981            response->postReply(mDequeueInputReplyID);
982
983            mFlags &= ~kFlagDequeueInputPending;
984            mDequeueInputReplyID = 0;
985            break;
986        }
987
988        case kWhatQueueInputBuffer:
989        {
990            uint32_t replyID;
991            CHECK(msg->senderAwaitsResponse(&replyID));
992
993            if (mState != STARTED || (mFlags & kFlagStickyError)) {
994                sp<AMessage> response = new AMessage;
995                response->setInt32("err", INVALID_OPERATION);
996
997                response->postReply(replyID);
998                break;
999            }
1000
1001            status_t err = onQueueInputBuffer(msg);
1002
1003            sp<AMessage> response = new AMessage;
1004            response->setInt32("err", err);
1005            response->postReply(replyID);
1006            break;
1007        }
1008
1009        case kWhatDequeueOutputBuffer:
1010        {
1011            uint32_t replyID;
1012            CHECK(msg->senderAwaitsResponse(&replyID));
1013
1014            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
1015                break;
1016            }
1017
1018            int64_t timeoutUs;
1019            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
1020
1021            if (timeoutUs == 0ll) {
1022                sp<AMessage> response = new AMessage;
1023                response->setInt32("err", -EAGAIN);
1024                response->postReply(replyID);
1025                break;
1026            }
1027
1028            mFlags |= kFlagDequeueOutputPending;
1029            mDequeueOutputReplyID = replyID;
1030
1031            if (timeoutUs > 0ll) {
1032                sp<AMessage> timeoutMsg =
1033                    new AMessage(kWhatDequeueOutputTimedOut, id());
1034                timeoutMsg->setInt32(
1035                        "generation", ++mDequeueOutputTimeoutGeneration);
1036                timeoutMsg->post(timeoutUs);
1037            }
1038            break;
1039        }
1040
1041        case kWhatDequeueOutputTimedOut:
1042        {
1043            int32_t generation;
1044            CHECK(msg->findInt32("generation", &generation));
1045
1046            if (generation != mDequeueOutputTimeoutGeneration) {
1047                // Obsolete
1048                break;
1049            }
1050
1051            CHECK(mFlags & kFlagDequeueOutputPending);
1052
1053            sp<AMessage> response = new AMessage;
1054            response->setInt32("err", -EAGAIN);
1055            response->postReply(mDequeueOutputReplyID);
1056
1057            mFlags &= ~kFlagDequeueOutputPending;
1058            mDequeueOutputReplyID = 0;
1059            break;
1060        }
1061
1062        case kWhatReleaseOutputBuffer:
1063        {
1064            uint32_t replyID;
1065            CHECK(msg->senderAwaitsResponse(&replyID));
1066
1067            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1068                sp<AMessage> response = new AMessage;
1069                response->setInt32("err", INVALID_OPERATION);
1070
1071                response->postReply(replyID);
1072                break;
1073            }
1074
1075            status_t err = onReleaseOutputBuffer(msg);
1076
1077            sp<AMessage> response = new AMessage;
1078            response->setInt32("err", err);
1079            response->postReply(replyID);
1080            break;
1081        }
1082
1083        case kWhatGetBuffers:
1084        {
1085            uint32_t replyID;
1086            CHECK(msg->senderAwaitsResponse(&replyID));
1087
1088            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1089                sp<AMessage> response = new AMessage;
1090                response->setInt32("err", INVALID_OPERATION);
1091
1092                response->postReply(replyID);
1093                break;
1094            }
1095
1096            int32_t portIndex;
1097            CHECK(msg->findInt32("portIndex", &portIndex));
1098
1099            Vector<sp<ABuffer> > *dstBuffers;
1100            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
1101
1102            dstBuffers->clear();
1103            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
1104
1105            for (size_t i = 0; i < srcBuffers.size(); ++i) {
1106                const BufferInfo &info = srcBuffers.itemAt(i);
1107
1108                dstBuffers->push_back(
1109                        (portIndex == kPortIndexInput && mCrypto != NULL)
1110                                ? info.mEncryptedData : info.mData);
1111            }
1112
1113            (new AMessage)->postReply(replyID);
1114            break;
1115        }
1116
1117        case kWhatFlush:
1118        {
1119            uint32_t replyID;
1120            CHECK(msg->senderAwaitsResponse(&replyID));
1121
1122            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1123                sp<AMessage> response = new AMessage;
1124                response->setInt32("err", INVALID_OPERATION);
1125
1126                response->postReply(replyID);
1127                break;
1128            }
1129
1130            mReplyID = replyID;
1131            setState(FLUSHING);
1132
1133            mCodec->signalFlush();
1134            returnBuffersToCodec();
1135            break;
1136        }
1137
1138        case kWhatGetOutputFormat:
1139        {
1140            uint32_t replyID;
1141            CHECK(msg->senderAwaitsResponse(&replyID));
1142
1143            if ((mState != STARTED && mState != FLUSHING)
1144                    || (mFlags & kFlagStickyError)
1145                    || mOutputFormat == NULL) {
1146                sp<AMessage> response = new AMessage;
1147                response->setInt32("err", INVALID_OPERATION);
1148
1149                response->postReply(replyID);
1150                break;
1151            }
1152
1153            sp<AMessage> response = new AMessage;
1154            response->setMessage("format", mOutputFormat);
1155            response->postReply(replyID);
1156            break;
1157        }
1158
1159        case kWhatRequestIDRFrame:
1160        {
1161            mCodec->signalRequestIDRFrame();
1162            break;
1163        }
1164
1165        case kWhatRequestActivityNotification:
1166        {
1167            CHECK(mActivityNotify == NULL);
1168            CHECK(msg->findMessage("notify", &mActivityNotify));
1169
1170            postActivityNotificationIfPossible();
1171            break;
1172        }
1173
1174        default:
1175            TRESPASS();
1176    }
1177}
1178
1179void MediaCodec::extractCSD(const sp<AMessage> &format) {
1180    mCSD.clear();
1181
1182    size_t i = 0;
1183    for (;;) {
1184        sp<ABuffer> csd;
1185        if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
1186            break;
1187        }
1188
1189        mCSD.push_back(csd);
1190        ++i;
1191    }
1192
1193    ALOGV("Found %u pieces of codec specific data.", mCSD.size());
1194}
1195
1196status_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
1197    CHECK(!mCSD.empty());
1198
1199    BufferInfo *info =
1200        &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex);
1201
1202    sp<ABuffer> csd = *mCSD.begin();
1203    mCSD.erase(mCSD.begin());
1204
1205    const sp<ABuffer> &codecInputData =
1206        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
1207
1208    if (csd->size() > codecInputData->capacity()) {
1209        return -EINVAL;
1210    }
1211
1212    memcpy(codecInputData->data(), csd->data(), csd->size());
1213
1214    AString errorDetailMsg;
1215
1216    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
1217    msg->setSize("index", bufferIndex);
1218    msg->setSize("offset", 0);
1219    msg->setSize("size", csd->size());
1220    msg->setInt64("timeUs", 0ll);
1221    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
1222    msg->setPointer("errorDetailMsg", &errorDetailMsg);
1223
1224    return onQueueInputBuffer(msg);
1225}
1226
1227void MediaCodec::setState(State newState) {
1228    if (newState == INITIALIZED || newState == UNINITIALIZED) {
1229        delete mSoftRenderer;
1230        mSoftRenderer = NULL;
1231
1232        mCrypto.clear();
1233        setNativeWindow(NULL);
1234
1235        mOutputFormat.clear();
1236        mFlags &= ~kFlagOutputFormatChanged;
1237        mFlags &= ~kFlagOutputBuffersChanged;
1238        mFlags &= ~kFlagStickyError;
1239
1240        mActivityNotify.clear();
1241    }
1242
1243    mState = newState;
1244
1245    cancelPendingDequeueOperations();
1246}
1247
1248void MediaCodec::returnBuffersToCodec() {
1249    returnBuffersToCodecOnPort(kPortIndexInput);
1250    returnBuffersToCodecOnPort(kPortIndexOutput);
1251}
1252
1253void MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
1254    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1255
1256    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1257
1258    for (size_t i = 0; i < buffers->size(); ++i) {
1259        BufferInfo *info = &buffers->editItemAt(i);
1260
1261        if (info->mNotify != NULL) {
1262            sp<AMessage> msg = info->mNotify;
1263            info->mNotify = NULL;
1264            info->mOwnedByClient = false;
1265
1266            if (portIndex == kPortIndexInput) {
1267                msg->setInt32("err", ERROR_END_OF_STREAM);
1268            }
1269            msg->post();
1270        }
1271    }
1272
1273    mAvailPortBuffers[portIndex].clear();
1274}
1275
1276size_t MediaCodec::updateBuffers(
1277        int32_t portIndex, const sp<AMessage> &msg) {
1278    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1279
1280    void *bufferID;
1281    CHECK(msg->findPointer("buffer-id", &bufferID));
1282
1283    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
1284
1285    for (size_t i = 0; i < buffers->size(); ++i) {
1286        BufferInfo *info = &buffers->editItemAt(i);
1287
1288        if (info->mBufferID == bufferID) {
1289            CHECK(info->mNotify == NULL);
1290            CHECK(msg->findMessage("reply", &info->mNotify));
1291
1292            mAvailPortBuffers[portIndex].push_back(i);
1293
1294            return i;
1295        }
1296    }
1297
1298    TRESPASS();
1299
1300    return 0;
1301}
1302
1303status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
1304    size_t index;
1305    size_t offset;
1306    size_t size;
1307    int64_t timeUs;
1308    uint32_t flags;
1309    CHECK(msg->findSize("index", &index));
1310    CHECK(msg->findSize("offset", &offset));
1311    CHECK(msg->findInt64("timeUs", &timeUs));
1312    CHECK(msg->findInt32("flags", (int32_t *)&flags));
1313
1314    const CryptoPlugin::SubSample *subSamples;
1315    size_t numSubSamples;
1316    const uint8_t *key;
1317    const uint8_t *iv;
1318    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
1319
1320    // We allow the simpler queueInputBuffer API to be used even in
1321    // secure mode, by fabricating a single unencrypted subSample.
1322    CryptoPlugin::SubSample ss;
1323
1324    if (msg->findSize("size", &size)) {
1325        if (mCrypto != NULL) {
1326            ss.mNumBytesOfClearData = size;
1327            ss.mNumBytesOfEncryptedData = 0;
1328
1329            subSamples = &ss;
1330            numSubSamples = 1;
1331            key = NULL;
1332            iv = NULL;
1333        }
1334    } else {
1335        if (mCrypto == NULL) {
1336            return -EINVAL;
1337        }
1338
1339        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
1340        CHECK(msg->findSize("numSubSamples", &numSubSamples));
1341        CHECK(msg->findPointer("key", (void **)&key));
1342        CHECK(msg->findPointer("iv", (void **)&iv));
1343
1344        int32_t tmp;
1345        CHECK(msg->findInt32("mode", &tmp));
1346
1347        mode = (CryptoPlugin::Mode)tmp;
1348
1349        size = 0;
1350        for (size_t i = 0; i < numSubSamples; ++i) {
1351            size += subSamples[i].mNumBytesOfClearData;
1352            size += subSamples[i].mNumBytesOfEncryptedData;
1353        }
1354    }
1355
1356    if (index >= mPortBuffers[kPortIndexInput].size()) {
1357        return -ERANGE;
1358    }
1359
1360    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
1361
1362    if (info->mNotify == NULL || !info->mOwnedByClient) {
1363        return -EACCES;
1364    }
1365
1366    if (offset + size > info->mData->capacity()) {
1367        return -EINVAL;
1368    }
1369
1370    sp<AMessage> reply = info->mNotify;
1371    info->mData->setRange(offset, size);
1372    info->mData->meta()->setInt64("timeUs", timeUs);
1373
1374    if (flags & BUFFER_FLAG_EOS) {
1375        info->mData->meta()->setInt32("eos", true);
1376    }
1377
1378    if (flags & BUFFER_FLAG_CODECCONFIG) {
1379        info->mData->meta()->setInt32("csd", true);
1380    }
1381
1382    if (mCrypto != NULL) {
1383        if (size > info->mEncryptedData->capacity()) {
1384            return -ERANGE;
1385        }
1386
1387        AString *errorDetailMsg;
1388        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
1389
1390        ssize_t result = mCrypto->decrypt(
1391                (mFlags & kFlagIsSecure) != 0,
1392                key,
1393                iv,
1394                mode,
1395                info->mEncryptedData->base() + offset,
1396                subSamples,
1397                numSubSamples,
1398                info->mData->base(),
1399                errorDetailMsg);
1400
1401        if (result < 0) {
1402            return result;
1403        }
1404
1405        info->mData->setRange(0, result);
1406    }
1407
1408    reply->setBuffer("buffer", info->mData);
1409    reply->post();
1410
1411    info->mNotify = NULL;
1412    info->mOwnedByClient = false;
1413
1414    return OK;
1415}
1416
1417status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
1418    size_t index;
1419    CHECK(msg->findSize("index", &index));
1420
1421    int32_t render;
1422    if (!msg->findInt32("render", &render)) {
1423        render = 0;
1424    }
1425
1426    if (mState != STARTED) {
1427        return -EINVAL;
1428    }
1429
1430    if (index >= mPortBuffers[kPortIndexOutput].size()) {
1431        return -ERANGE;
1432    }
1433
1434    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
1435
1436    if (info->mNotify == NULL || !info->mOwnedByClient) {
1437        return -EACCES;
1438    }
1439
1440    if (render) {
1441        info->mNotify->setInt32("render", true);
1442
1443        if (mSoftRenderer != NULL) {
1444            mSoftRenderer->render(
1445                    info->mData->data(), info->mData->size(), NULL);
1446        }
1447    }
1448
1449    info->mNotify->post();
1450    info->mNotify = NULL;
1451    info->mOwnedByClient = false;
1452
1453    return OK;
1454}
1455
1456ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
1457    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
1458
1459    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
1460
1461    if (availBuffers->empty()) {
1462        return -EAGAIN;
1463    }
1464
1465    size_t index = *availBuffers->begin();
1466    availBuffers->erase(availBuffers->begin());
1467
1468    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
1469    CHECK(!info->mOwnedByClient);
1470    info->mOwnedByClient = true;
1471
1472    return index;
1473}
1474
1475status_t MediaCodec::setNativeWindow(
1476        const sp<SurfaceTextureClient> &surfaceTextureClient) {
1477    status_t err;
1478
1479    if (mNativeWindow != NULL) {
1480        err = native_window_api_disconnect(
1481                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
1482
1483        if (err != OK) {
1484            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
1485                    strerror(-err), err);
1486        }
1487
1488        mNativeWindow.clear();
1489    }
1490
1491    if (surfaceTextureClient != NULL) {
1492        err = native_window_api_connect(
1493                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
1494
1495        if (err != OK) {
1496            ALOGE("native_window_api_connect returned an error: %s (%d)",
1497                    strerror(-err), err);
1498
1499            return err;
1500        }
1501
1502        mNativeWindow = surfaceTextureClient;
1503    }
1504
1505    return OK;
1506}
1507
1508void MediaCodec::postActivityNotificationIfPossible() {
1509    if (mActivityNotify == NULL) {
1510        return;
1511    }
1512
1513    if ((mFlags & (kFlagStickyError
1514                    | kFlagOutputBuffersChanged
1515                    | kFlagOutputFormatChanged))
1516            || !mAvailPortBuffers[kPortIndexInput].empty()
1517            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
1518        mActivityNotify->post();
1519        mActivityNotify.clear();
1520    }
1521}
1522
1523}  // namespace android
1524