ACodec.cpp revision 4811923e80a8abefa278307ebf8cc9b0294ba67f
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
4090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar#include <media/stagefright/MediaCodec.h>
41afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
45b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
52777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar#include "include/DataConverter.h"
564811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim#include "include/SecureBuffer.h"
577e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include "include/SharedMemoryBuffer.h"
5873dd808754c641fe798273d356ee38368715fa7bLajos Molnar#include "omx/OMXUtils.h"
59496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangusing binder::Status;
636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
646e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnarenum {
656e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
666e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar};
676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
976d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangstatic inline status_t statusFromBinderStatus(const Status &status) {
986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (status.isOk()) {
996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return OK;
1006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1016d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err;
1026d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.serviceSpecificErrorCode()) != OK) {
1036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1046d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.transactionError()) != OK) {
1066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1076d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1086d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Other exception
1096d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return UNKNOWN_ERROR;
1106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
1116d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
114251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
117251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
12526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
12626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
12726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
128984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    virtual ~MessageList() {
129984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    }
13026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
13126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
13226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
13326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
13426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
13526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
13626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
1375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnarstatic sp<DataConverter> getCopyConverter() {
1385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
1395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static sp<DataConverter> sCopyConverter;        // zero-inited
1405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
1415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return sCopyConverter;
1425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar}
1435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
15226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
153984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        if (messages.empty()) {
154984a54322f7c70bc75e862d91bdd975814872affLajos Molnar            return;
155984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        }
156984a54322f7c70bc75e862d91bdd975814872affLajos Molnar
157984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        sp<AMessage> notify = mNotify->dup();
15826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
15926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
16126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
16426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
16526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
16626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
16726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
16926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
17026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
17126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
17226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
17526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
17626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
17726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
17826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
17926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
18226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
18326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
18526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
18726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
18826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
19026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
19126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
19326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
19426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
19526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
19626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
19726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
19926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
20026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
20390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
20490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
20590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
20690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
20790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
20890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
20990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
21090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
21126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
21226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
21326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
21426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
21526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
21626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
21726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
21826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
233090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
25626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
26026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
26126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
26226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
26326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
26426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
26515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
27115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
27215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
27590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
284090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit DeathNotifier(const sp<AMessage> &notify)
285ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
286ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
287ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
288ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
289ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
290ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
291ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
292ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
293ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
294ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
295ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
296ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
297ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
298ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
299ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
300ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
302090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit UninitializedState(ACodec *codec);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
313ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
320090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedState(ACodec *codec);
321c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
322c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
328c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3318f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
332c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
335d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
336d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
340c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
343090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedToIdleState(ACodec *codec);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
359090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToExecutingState(ACodec *codec);
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
373090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingState(ACodec *codec);
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
376054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
384349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
385349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
39290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
395349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
396349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
403090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit OutputPortSettingsChangedState(ACodec *codec);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
41190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
420090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingToIdleState(ACodec *codec);
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
442090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToLoadedState(ACodec *codec);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
457090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit FlushingState(ACodec *codec);
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
47915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
48015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
48115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
48215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
48315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
48415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
48515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
48815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
48915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
49015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
49115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
49215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
49315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
49415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
49515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
49615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
49715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
49815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
49915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
50115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
50215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
50315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
50415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
50515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
50715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
50815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
50915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
510f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
511b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    : mSampleRate(0),
512d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang      mNodeGeneration(0),
513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
514e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
515fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
5168db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
517c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
518346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5199806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
52054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
521f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang      mIsLegacyVP9Decoder(false),
5229806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5239806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
524e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5259806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
526054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
527054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
528054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mInputMetadataType(kMetadataBufferTypeInvalid),
529054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mOutputMetadataType(kMetadataBufferTypeInvalid),
530011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
531054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
53394ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
53537b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
5362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
537609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
538ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
5398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
540db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
541db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0) {
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
543c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
556dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
559fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
566f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
570f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
576a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5771d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
578a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
579a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
580a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
581a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5825778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5841d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5885778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
6081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
6097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6118f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
612d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
6138f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
614d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
615d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
616d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
617d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6225778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6231d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
626f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6277a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
631f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6321d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
635c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6361d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
63930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
64030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6411d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
64230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
645496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
647496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
648496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
654054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6554dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
656054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
657054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
671e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
690e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
691098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    // no need to reconnect as we will not dequeue all buffers
692098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(
693098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            nativeWindow, &usageBits,
694098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            !storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment /* reconnect */);
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
699f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
700e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
701e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
702e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
703e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
704e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
705e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
735dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
736dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
737dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
743054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
744011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
7451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
746598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa            ALOGV("skipping buffer");
7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
761054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
7621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
76315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
76715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
76815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
781484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
782484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
783484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
784484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
785484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
787e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
799054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()) {
800054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
810d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
813054219874873b41f1c815552987c10465c34ba2bLajos Molnar            MetadataBufferType type =
814054219874873b41f1c815552987c10465c34ba2bLajos Molnar                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
8155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
8163e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            if (type == kMetadataBufferTypeANWBuffer) {
817054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
8183e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            } else if (type == kMetadataBufferTypeNativeHandleSource) {
8193e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                bufSize = sizeof(VideoNativeHandleMetadata);
820054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
821054219874873b41f1c815552987c10465c34ba2bLajos Molnar
822054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // If using gralloc or native source input metadata buffers, allocate largest
823054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // metadata size as we prefer to generate native source metadata, but component
8245fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // may require gralloc source. For camera source, allocate at least enough
8255fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // size for native metadata buffers.
8265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t allottedSize = bufSize;
8273e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            if (portIndex == kPortIndexInput && type == kMetadataBufferTypeANWBuffer) {
828054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
8295fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
8305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                bufSize = max(bufSize, sizeof(VideoNativeMetadata));
8315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
8325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8355b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
843054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
844054219874873b41f1c815552987c10465c34ba2bLajos Molnar
84528edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
84628edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            ALOGV("[%s] Allocating %u buffers of size %zu/%zu (from %u using %s) on %s port",
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
849054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
8535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
85428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
85528edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
85628edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
85728edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
85828edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
85928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
8605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
8615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
86234e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
86334e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
86434e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
86528edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8697e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            const sp<AMessage> &format = portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
870054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
871054219874873b41f1c815552987c10465c34ba2bLajos Molnar                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
8725581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
873777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
874777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
876ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
877ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
87815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
87990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
881e33d922fd86699c664a15f09e6d8b2e422736a40Lajos Molnar                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
882ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
883ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
884a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
8851b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    sp<NativeHandle> native_handle;
886d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->allocateSecureBuffer(
887d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            portIndex, bufSize, &info.mBufferID,
888a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
889a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
8904811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                    info.mData = (native_handle == NULL)
8914811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            ? new SecureBuffer(format, ptr, bufSize)
8924811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            : new SecureBuffer(format, native_handle, bufSize);
8935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = info.mData;
8945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
89521b46588d022d0c22d7c7c08e919d7a9c5cd76e3Chong Zhang                    err = mOMXNode->useBuffer(
89621b46588d022d0c22d7c7c08e919d7a9c5cd76e3Chong Zhang                            portIndex, mem, &info.mBufferID, allottedSize);
897ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
898ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
899ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
9007e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    info.mCodecData = new SharedMemoryBuffer(format, mem);
9015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecRef = mem;
9025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
903054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (type == kMetadataBufferTypeANWBuffer) {
904054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
905054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
9065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
9075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // if we require conversion, allocate conversion buffer for client use;
9085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // otherwise, reuse codec buffer
9095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (mConverter[portIndex] != NULL) {
9105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        CHECK_GT(conversionBufferSize, (size_t)0);
9115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mem = mDealer[portIndex]->allocate(conversionBufferSize);
9125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        if (mem == NULL|| mem->pointer() == NULL) {
9135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            return NO_MEMORY;
9145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        }
9157e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                        info.mData = new SharedMemoryBuffer(format, mem);
9165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = mem;
9175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else {
9185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = info.mCodecData;
9195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = info.mCodecRef;
9205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
9241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
9251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
933d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
936eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
937eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
938eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
940eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
9414811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        desc->addBuffer(info.mBufferID, info.mData);
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
944eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
950e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
951098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
952098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        bool reconnect) {
9531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
957d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
958d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
9591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
9611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
965d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
9661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
9671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
9681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
9691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
9701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
9721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
9741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
9751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
977f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
978e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
979b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
980fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
981fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
982fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
9831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
9841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
9851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
9861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
9871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
9881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
9891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
990098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            usage,
991098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            reconnect);
9921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
9931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
9951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
996098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        OMX_U32 *minUndequeuedBuffers, bool preregister) {
997098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar
9981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
10001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
10011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1002d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
1003d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
10041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
1006098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        err = setupNativeWindowSizeFormatAndUsage(
1007098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar                mNativeWindow.get(), &mNativeWindowUsageBits, preregister /* reconnect */);
10081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
1010e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
10111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
10121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1014ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
1015ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
1016ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
1017ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1018ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1019ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
1020d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1021d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1022ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1023ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
1024ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
1025ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
1026ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
1027ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1028ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1029054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
1030258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
1031258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1032054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
1033258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1034258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
103529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1036258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
1037258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
1038258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1039258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1040e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
1041e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
10421faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
10431faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1044e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1045e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
1046e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
1047e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1048e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
1049e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
1050e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
10511faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
10521faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1053e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
1054e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1055258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1056d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1057d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1058258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1059e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1060e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1061e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1062e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1063e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1064609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1065e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1066e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1067e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1068258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1069258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1070258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1071258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
107629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1081054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1082054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1083054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1084054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1085054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1089098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
1090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1092e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1093054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1094054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
10953298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
10963298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
10973298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10983298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1099609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
11058ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
110615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
110715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
110929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
111474006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
111574006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
111615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
111715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
111890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
111974006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
112074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
112174006804065941841883c4b46ee785070164023fJamie Gennis
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
1123d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->useGraphicBuffer(
1124d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, graphicBuffer, &bufferId);
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1126609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
112774006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
113174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
113274006804065941841883c4b46ee785070164023fJamie Gennis
1133609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
1144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
114574006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1147054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1148054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1149054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
11543175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
11553175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
11563175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
11573175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
11583175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
11593fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1162054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
11633298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
11643298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
11653298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
11663298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1170054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1173098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers,
1174098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            mLegacyAdaptiveExperiment /* preregister */);
1175054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1176054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1177e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1178054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1179e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1180e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1181e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1182054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1183054219874873b41f1c815552987c10465c34ba2bLajos Molnar            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
118428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar    size_t totalSize = bufferCount * align(bufSize, MemoryDealer::getAllocationAlignment());
1185e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1186e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1187e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
1188e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1189e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1190e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
119115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
119290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1193e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1194e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1195e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1196054219874873b41f1c815552987c10465c34ba2bLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
11975581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
1198777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
1199777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1200054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1201054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1202054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
12037e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        info.mData = new SharedMemoryBuffer(mOutputFormat, mem);
12045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mMemRef = mem;
12055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
12065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecRef = mem;
1207e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1208e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
1209d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->useBuffer(
1210d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, mem, &info.mBufferID, mem->size());
1211e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1212e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1213e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1214e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1215e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1216e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1217011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1218e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1219011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1220011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1221011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1222011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1223011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1224011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1225011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1226011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1227011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1228e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1229e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1230011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
123115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd;
123215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1233011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1234011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1235011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1236011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1237011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1238011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1239d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            mOMXNode->updateGraphicBufferInMeta(
1240d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    kPortIndexOutput, graphicBuffer, info->mBufferID);
1241e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
124215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1243e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1244011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1245011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1246011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1247011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
12483175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (info->mStatus == BufferInfo::OWNED_BY_US) {
12493175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                status_t error = cancelBufferToNativeWindow(info);
12503175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                if (err == OK) {
12513175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                    err = error;
12523175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                }
1253011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1254011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1255011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1256011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1257011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1258011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1259011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1260054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1263054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1264054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1265054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1266054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1267054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1268054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1269054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
12700806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1271054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
12720806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1273054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1274609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1275054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1276054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1277054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
127815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
1279d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
128015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1281777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1282777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1283777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1284054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1285777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1286054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1287054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
128815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
128915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
129015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
129115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
129215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
129315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
129415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
129515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
129615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
129715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
12980806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
12990806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
13000806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
13010806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
13020806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
13030806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
13040806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
13050806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
13060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
13070806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
13080806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13090806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13100806340688c937e7b78c2d89db3809274130df4eLajos Molnar
13110806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
13120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
13130806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
13140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
13150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
13160806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
13170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
13180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
13190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
13200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
13210806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13220806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13230806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1327609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
133015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
133215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
133315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13353fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
13363fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
13370806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13403fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
134390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
134490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
134590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
134690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
134790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
134890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
134990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
135090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
135190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
135290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
135390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
135490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
135590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
135690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
135790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
135890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
135990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
136090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
136190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = mNotify->dup();
136290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
136390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
136490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
136590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
136690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
136790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
136890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1369604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1370604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1371604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1372604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1373604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1374604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
137590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
137690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
137790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
137890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
137990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->post();
138090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
138190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
138290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1383f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
13848ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1385054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1386ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1387ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1388ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1389ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1390ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1391ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1392ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1393346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1394346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1395346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1396346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1397346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
139815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1399dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
140015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
140115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
140215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1403dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1404dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1406dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1407b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1408b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1409dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1410dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1411dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
141290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1413dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1414dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1415dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1416dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1417dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1418dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1419dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1420dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1421dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1422dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1423dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1424dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
142590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1426dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1427dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
142815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
142990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1430dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1431dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1432dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1434dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1435dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1436dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1437dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1438dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1439054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1440dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1441dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1442dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1443dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1444dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1445dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1447dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1448054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1449dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1450dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1451b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1452b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1453dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1454dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1455054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1456054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1457054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1458054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1459054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1460054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1461054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1462054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
14650806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
14660806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
14670806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1468054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1469054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14700806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
14710806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
14720806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
147315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
147490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
147590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1476d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1477d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mOMXNode->updateGraphicBufferInMeta(
1478d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            kPortIndexOutput, oldest->mGraphicBuffer, oldest->mBufferID);
1479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1480054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1481054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata *grallocMeta =
14827e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->data());
1483054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1484054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1485054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14867c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)grallocMeta->pHandle,
14877e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                oldest->mGraphicBuffer->handle, oldest->mData->data());
1488054219874873b41f1c815552987c10465c34ba2bLajos Molnar    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1489054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata *nativeMeta =
14907e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->data());
1491054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1492054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1493054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14947c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)nativeMeta->pBuffer,
14957e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->data());
1496054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
14990806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1503777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1504938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1505938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1506777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1507777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1508777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1509777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1514777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1517349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1518777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1519938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1520938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15242ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
15252ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
15262ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
15272ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1528777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1529777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1530777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1531777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1535777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
15400806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
154315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    MetadataBufferType type =
154415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
154515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
154615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
154715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
154815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
154915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
155015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
155115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
155215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
155315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
15540806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
15550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
15560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
15570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
15580806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
15590806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15610806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1562d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
15630806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
15640806340688c937e7b78c2d89db3809274130df4eLajos Molnar
15650806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
15660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
15670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
15680806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
157115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
157215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
157315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
157415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1575604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1576604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1577604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1578604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
157990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1580d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    // remove buffer even if mOMXNode->freeBuffer fails
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1582777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1585f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
15860806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1598777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
16041ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime);
16055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
16065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
16075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
1608d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = SetComponentRole(mOMXNode, role);
16095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
16105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
16115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
16125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
16135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
16145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
16155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1623b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1624b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1625b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1626e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1629054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mInputMetadataType = kMetadataBufferTypeInvalid;
1630054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mOutputMetadataType = kMetadataBufferTypeInvalid;
16318db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
16392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
16402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
16412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
164596bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    // propagate bitrate to the output so that the muxer has it
164696bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    if (encoder && msg->findInt32("bitrate", &bitRate)) {
164796bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
164896bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
164996bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("bitrate", bitRate);
165096bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("max-bitrate", bitRate);
165196bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    }
165296bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar
1653d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1654d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
16553e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
16563e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && storeMeta != kMetadataBufferTypeInvalid) {
16573e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mInputMetadataType = (MetadataBufferType)storeMeta;
1658d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->storeMetaDataInBuffers(
1659d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1661054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1662308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1663d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1664054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
16653e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        } else if (storeMeta == kMetadataBufferTypeANWBuffer
16663e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                && mInputMetadataType == kMetadataBufferTypeGrallocSource) {
16673e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            // IOMX translates ANWBuffers to gralloc source already.
16683e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mInputMetadataType = (MetadataBufferType)storeMeta;
1669054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1670c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1671c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1672d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
1673d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1674c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1675c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1676c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1677c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1678054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1679d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1680308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
16813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
16823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
16833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
16843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
1685d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getExtensionIndex(
1686d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
16873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
16893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
16903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
16913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
16923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1693d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(index, &params, sizeof(params));
16943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
16953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
16973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
16983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
16993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
17013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
17033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1704308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1705308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1706308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1707308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
17088db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1709308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1710308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
17113e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
1712308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1713308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
17143e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mOutputMetadataType = kMetadataBufferTypeNativeHandleSource;
1715d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->storeMetaDataInBuffers(kPortIndexOutput, enable, &mOutputMetadataType);
1716308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1717308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1718308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1719308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1720a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1721a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1722a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1723a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1724a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1725a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
172694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
172794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
17282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
17292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
17302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
173137b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
173237b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
173337b2b389139ed638831e49708c947863eef631efRonghua Wu        }
173437b2b389139ed638831e49708c947863eef631efRonghua Wu
17352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
17362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
173794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
173872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
173972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
174072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
174172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
174272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
174372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1744308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1745308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
17463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
17480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
17493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1750b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1751011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1752e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1753e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
17541713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
17551713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
17561713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
17571713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
17581713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
17591713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
17601713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
17611713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
17621713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
17631713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1764a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1765a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        if (mFlags & kFlagIsSecure) {
1766a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            // use native_handles for secure input buffers
1767d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->enableNativeBuffers(
1768d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
1769a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            ALOGI_IF(err != OK, "falling back to non-native_handles");
1770a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = OK; // ignore error for now
1771a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1772e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
17733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
17741de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
17751de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
17765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17776597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
17786597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
17796597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
17806597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
17816597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
17826597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
17836597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
1784d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t temp = mOMXNode->setConfig(
1785d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
17866597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
17876597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
17886597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
17896597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
17906597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
17916597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
17926597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
17936597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
17946597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
17955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
17965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
17975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
17985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1799ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
18005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
180197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
180297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
18035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
18045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
18065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
180797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
18085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
18095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1810fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1811fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1812d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1813d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1814d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1815d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1816d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mOMXNode->prepareForAdaptivePlayback(
1817d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1818d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1819d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1820d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
18213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
18223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1823d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1824d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1825d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1826d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1827d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1828d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
18295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1830ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1831ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1832ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
18333fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
18343fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
18353fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
18363fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
18373fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
18383fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
18393fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
18403fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
18413fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
18425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
18433e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            mOutputMetadataType = kMetadataBufferTypeANWBuffer;
1844d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->storeMetaDataInBuffers(
1845d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
18465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
18475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1848fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
18505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
18515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
18525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
18535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
18555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
18565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
18575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
18585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
18595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
18615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
18625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
18635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
18645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
18655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
18665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
18675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
18685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
18695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
18705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
18715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
18735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
18745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
18755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
18765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
18775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
18785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1879d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->prepareForAdaptivePlayback(
1880d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
18815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
18825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
18835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
18845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
18865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
18875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
18885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
18895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
18915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
18925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
18935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
18945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
18955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
1896054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
1897011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1898011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1899011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
19005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1901fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
19020167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
19035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
19045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
19055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
19065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
19075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
19080167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1909e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1910e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1911e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1912e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1913e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1914e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1915e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
19185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
19195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
19205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
19215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
1922308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
19233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
19243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
19253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
19263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
19273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
19283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
1931b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1933b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
19373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
19383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
19411de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
19423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
19453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1948777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1949777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
19503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
19523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
19533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
19543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
19553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1956777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1957777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1958777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1959777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
19613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1962777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1963777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1964777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1965777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
19673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
19681ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                if (!IsFlexibleColorFormat(
1969d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
19703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
19713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
19723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
19733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
19743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
1975e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
19763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
19773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
1978054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (storingMetadataInDecodedBuffers()) {
1979d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        err = mOMXNode->storeMetaDataInBuffers(
1980d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
1981054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
19823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
19833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
19843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
19853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
1987d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        err = mOMXNode->enableNativeBuffers(
1988d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
19893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
19913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
19923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
19933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
1994b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
1995b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
19963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
19983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
19993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
20023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
20033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
200442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
200542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
200642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
200742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
200842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
200942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
201042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
201142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
201242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
201342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
201442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
201542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
201642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2023aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
2024b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
20258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
20262965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
20278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
2028ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
2029ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
2030ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
2031aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
2032aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
2033aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
2034b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2035b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
2036b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
2037ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20388045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
20398045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
20408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20412965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
20422965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
20432965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
20442965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
20458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
20468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
20488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
20508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
20528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
20548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
20568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
20588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
20608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
20628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
20648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2066ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
20674471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
20682965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
20692965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2071729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2073729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2075729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2076729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2077729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2078729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2079729de186450f78c099637e1fce743fe531862c52Andreas Huber
2080729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
208417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
208517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
208617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
208717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
208817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2091ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
20922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
20932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
20942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
20952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
20962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
20972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
20982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2099516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2100cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2101cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2102516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2103cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
21042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2105516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2106516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2107516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
21092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2110516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2111516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2112516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
21142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
21152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2116516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2117516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
21182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2119ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2120ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2121ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2122ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2123ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2124ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2125ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
21265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2127ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
212897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
212997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
213097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
213197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
213297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
213397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
213497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
213597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
213697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
21378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
21388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
21398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
21408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
21418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
21428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
21438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
21448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
21458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2147729de186450f78c099637e1fce743fe531862c52Andreas Huber
21484471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
21494471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
21504471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
21514471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
21528b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
21538b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
21548b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
21559806555d3930be43e11106281dee354820ac1c88Andreas Huber
21568b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
21578b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
21588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
21598b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
21609806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
21619806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
21629806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
21639806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
21649806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
21659806555d3930be43e11106281dee354820ac1c88Andreas Huber
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21738b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
21748b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
21758b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
21768b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21778b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2178ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2179ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2180ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2181ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2182ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2183ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2184ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2185ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2186ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2187ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2188697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
21894e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2190b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // trigger a kWhatOutputFormatChanged msg on first buffer
2191b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
21924e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2193777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2194777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2195777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2196777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2197777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2198777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2199777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2200777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
22015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // create data converters if needed
22035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!video && err == OK) {
22045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
22055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (encoder) {
22065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
22085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexInput] != NULL) {
22095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
22105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        } else {
22125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
22145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexOutput] != NULL) {
22155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
22165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
22185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
22195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22238b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
22248b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
22258b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
22268b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22278b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
22288b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
22298b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
2230d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t temp = mOMXNode->setConfig(
2231d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigPriority,
22328b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
22338b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
22348b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
22358b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22368b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
22378b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
22388b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2239ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2240ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2241ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2242ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2243ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2244ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2245ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2246ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2247ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2248ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2249ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2250ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2251ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2252ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2253ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2254ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2255ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2256ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2257ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2258d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2259d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2260ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2261ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2262ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2263ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2264ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2265ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2266ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2267870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2268870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2269870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2270870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2271d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getConfig(
2272d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2273870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2274870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2275870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2276870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2277870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2278870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2279870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2280870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2281870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2282870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2283d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2284d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2285870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2286870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2287870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2288870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2289870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2290870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2291870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2292870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2293870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2294870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2295870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2296d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2297d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2298870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2299870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2300870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2301870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2302870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2303870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2304870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2305870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2306870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2307870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2308870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2309870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2310870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2311870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2312870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2313870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2314870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2315d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2316d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2317870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2318870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2319870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2320870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2321870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2322870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2323870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2324870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2325870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2326870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2327870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2328870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2329870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2330870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2331870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2332870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2333870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2334870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2335870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2336870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2337870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2338870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2339870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2340870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2341870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2342870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2343d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2344d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
2345870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2346870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2347870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2348870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2349870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2350870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2351870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2352870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2353870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2354d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2355d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh,
2356d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &refreshParams, sizeof(refreshParams));
2357870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2358870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2359870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2360870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2361870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2362870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2363870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
23640f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnarstatus_t ACodec::configureTemporalLayers(
23650f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) {
23660f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!mIsVideo || !mIsEncoder) {
23670f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return INVALID_OPERATION;
23680f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23690f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23700f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString tsSchema;
23710f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!msg->findString("ts-schema", &tsSchema)) {
23720f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return OK;
23730f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23740f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23750f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numLayers = 0;
23760f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numBLayers = 0;
23770f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    int tags;
23780f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    char dummy;
23790f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
23800f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
23810f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
23820f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0) {
23830f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
23840f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
23850f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                    &numLayers, &dummy, &numBLayers, &dummy))
23860f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && (tags == 1 || (tags == 3 && dummy == '+'))
23870f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
23880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        numLayers += numBLayers;
23890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
23900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
23910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
23920f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
23930f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23940f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23950f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
23960f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    InitOMXParams(&layerParams);
23970f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    layerParams.nPortIndex = kPortIndexOutput;
23980f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2399d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2400d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2401d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &layerParams, sizeof(layerParams));
24020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
24040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
24050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (!(layerParams.eSupportedPatterns & pattern)) {
24060f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
24070f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24080f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24090f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numLayers = min(numLayers, layerParams.nLayerCountMax);
24100f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numBLayers = min(numBLayers, layerParams.nBLayerCountMax);
24110f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24120f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!inConfigure) {
24130f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
24140f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        InitOMXParams(&layerConfig);
24150f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPortIndex = kPortIndexOutput;
24160f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.ePattern = pattern;
24170f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPLayerCountActual = numLayers - numBLayers;
24180f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nBLayerCountActual = numBLayers;
24190f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
24200f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2421d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(
2422d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
24230f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerConfig, sizeof(layerConfig));
24240f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
24250f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.ePattern = pattern;
24260f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nPLayerCountActual = numLayers - numBLayers;
24270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nBLayerCountActual = numBLayers;
24280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.bBitrateRatiosSpecified = OMX_FALSE;
24290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2430d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2431d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
24320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerParams, sizeof(layerParams));
24330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24350f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString configSchema;
24360f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) {
24370f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers);
24380f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
24390f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("webrtc.vp8.%u", numLayers);
24400f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24410f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
24430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGW("Failed to set temporal layers to %s (requested %s)",
24440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                configSchema.c_str(), tsSchema.c_str());
24450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
24460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24470f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2448d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2449d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
24500f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            &layerParams, sizeof(layerParams));
24510f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24520f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err == OK) {
24530f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)",
24540f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                tsSchema.c_str(), configSchema.c_str(),
24550f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                asString(layerParams.ePattern), layerParams.ePattern,
24560f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                layerParams.nPLayerCountActual, layerParams.nBLayerCountActual);
24570f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24580f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        if (outputFormat.get() == mOutputFormat.get()) {
24590f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            mOutputFormat = mOutputFormat->dup(); // trigger an output format change event
24600f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        }
24610f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        // assume we got what we configured
24620f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        outputFormat->setString("ts-schema", configSchema);
24630f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24640f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    return err;
24650f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar}
24660f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2472d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2473d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2485d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2486d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2492d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2493d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2499777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2500777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2501777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2502777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
25136e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
2515d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2516d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPortFormat, &format, sizeof(format));
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25256e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
25266e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
25276e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
25286e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
25296e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
25306e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
25316e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2534d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2535d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPortFormat, &format, sizeof(format));
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2539aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
25408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
25412965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
25422965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2543ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2544ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2545ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2546ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
25575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2567d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2568d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2577d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2578d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2588d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2589d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2607aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2609b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2610b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2611b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2612b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2613b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2614b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2615b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2616b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2617b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2618b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2619b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2620b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2621b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2622b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2623b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2624b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2625b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2626b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2627b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2628b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2629b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2630b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2631b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2632b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2633b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2634b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2636d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2637d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2650d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2651d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2659ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2660ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2661ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2662ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2663ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2666dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
26678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
26688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
26698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
26708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
26718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
26728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
26732965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
26748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2675d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t res = mOMXNode->setParameter(
2676d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
26778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
26788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
2679d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mOMXNode->setParameter(
2680d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
26818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
26828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
26838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
26848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
2685b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    mSampleRate = sampleRate;
26868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
269097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
269197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
269297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
269397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
269497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
269597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
269697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
269797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
269897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
269997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
270097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
270197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
270297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
270397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
270497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
270597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
270697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2707d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2708d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
270997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
271097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
271197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
271297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
271397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
271497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
271597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
271697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2717d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2718d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
271997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
272097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
27218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
27228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
27238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
27248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
27258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
27278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
27288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
27318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
27328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
27338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
27368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
27378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
27388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2739d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2740d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
27418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
27438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
27448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
27458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
27478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
27488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2749d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2750d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
27518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
27528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
27555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
27615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
27755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
27765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
27775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
27785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
27795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
27805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
27815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
27825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
27835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
27845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
27855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
27895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
27905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
27915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
27945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
27955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2799729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2800729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2802729de186450f78c099637e1fce743fe531862c52Andreas Huber
2803d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2804d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2805729de186450f78c099637e1fce743fe531862c52Andreas Huber
2806729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2807729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2808729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2809729de186450f78c099637e1fce743fe531862c52Andreas Huber
2810729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
28125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2813d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2814d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2815729de186450f78c099637e1fce743fe531862c52Andreas Huber
28165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2819729de186450f78c099637e1fce743fe531862c52Andreas Huber
28205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
28215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
28225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
28235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2824729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2825729de186450f78c099637e1fce743fe531862c52Andreas Huber
282617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2827777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2828777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2829777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2831729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
283217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2833729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2834729de186450f78c099637e1fce743fe531862c52Andreas Huber
28352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
28362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
28372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
28392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
28402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
28412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
28422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
2844d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
28452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
28462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
28472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
28482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
28492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
2850d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
28512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
28522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
28532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
28542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
28552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
28562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
28572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
28582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
28592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
28602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
28612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
28622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2863729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
28645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
2865729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2866729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2867729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2868729de186450f78c099637e1fce743fe531862c52Andreas Huber
2869d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2870d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2871729de186450f78c099637e1fce743fe531862c52Andreas Huber
2872729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2873729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2874729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2875729de186450f78c099637e1fce743fe531862c52Andreas Huber
2876729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2877729de186450f78c099637e1fce743fe531862c52Andreas Huber
2878d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2879d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2880729de186450f78c099637e1fce743fe531862c52Andreas Huber
2881729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2882729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2883729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2884729de186450f78c099637e1fce743fe531862c52Andreas Huber
2885729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2886729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2887729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2888729de186450f78c099637e1fce743fe531862c52Andreas Huber
2889d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2890d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2891729de186450f78c099637e1fce743fe531862c52Andreas Huber
2892729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2893729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2894729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2895729de186450f78c099637e1fce743fe531862c52Andreas Huber
2896729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
28975b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    switch (encoding) {
28985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm8bit:
28995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataUnsigned;
29005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 8;
29015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcmFloat:
29035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataFloat;
29045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 32;
29055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm16bit:
29075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataSigned;
29085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 16;
29095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        default:
29115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            return BAD_VALUE;
29125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
2913729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2914729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2915729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2916729de186450f78c099637e1fce743fe531862c52Andreas Huber
2917c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2918c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2919729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2920729de186450f78c099637e1fce743fe531862c52Andreas Huber
2921d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2922d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
29235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // if we could not set up raw format to non-16-bit, try with 16-bit
29245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // NOTE: we will also verify this via readback, in case codec ignores these fields
29255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (err != OK && encoding != kAudioEncodingPcm16bit) {
29265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.eNumData = OMX_NumericalDataSigned;
29275b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.nBitPerSample = 16;
2928d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2929d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
29305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
29315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return err;
2932729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2933729de186450f78c099637e1fce743fe531862c52Andreas Huber
29345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
293597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
29365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
29375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2938d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->configureVideoTunnelMode(
2939d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
29405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
29415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
29425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
29435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
29445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
29465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
29475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
29485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
29495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
29505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
29515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
29525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
29535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
29545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
29580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
29590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29666e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2968d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2969d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat,
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2976229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2977229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
29780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
29791ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
2980d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
29810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2982229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2983229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2984229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2985229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2986229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30116e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
30126e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
30136e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
30146e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
30156e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
30166e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3023d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
3024d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
30300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
30310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
30320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
30330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
30340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
30350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
30360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
30370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
30380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
30390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
30400d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
30410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
30420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
30430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
30440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
30490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
30500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
30530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
3054d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3055d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat, &format, sizeof(format));
30560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
30570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
30580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
30590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
30600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
30610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
30620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
30630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
30650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
30660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
30680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
30710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
30720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
30730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
30740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
30750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
30760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
30790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
30800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
30811ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
3082d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
30830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
30840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
30850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
30860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
3088d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
3089d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3092e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
3093e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
3094e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3095e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
3096e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
30972472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3100e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
310194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
310294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3103a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
3105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3117e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3118e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3119e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3120e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3121e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3122e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3123e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3125e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3126e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3127e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3128e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3129e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3130e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3131e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3132e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3133e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3134e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3135e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3138a6bfb5060824f01041f956c733fec141504c280bHangyu Kuangstatus_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) {
3139a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
3140a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    InitOMXParams(&def);
3141a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nPortIndex = portIndex;
3142a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    status_t err;
3143a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
3144a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3145d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3146d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3147a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3148a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        return err;
3149a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3150a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nBufferCountActual = bufferNum;
3151d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3152d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3153a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3154a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        // Component could reject this request.
3155a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
3156a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3157a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3158a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    return OK;
3159a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang}
3160a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
31615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
31628338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3163b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
316489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
316589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
316689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
316789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
316889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
316989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3177f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    if (compressionFormat == OMX_VIDEO_CodingVP9) {
3178f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3179f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        InitOMXParams(&params);
3180f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nPortIndex = kPortIndexInput;
3181f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        // Check if VP9 decoder advertises supported profiles.
3182f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nProfileIndex = 0;
3183d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3184f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                OMX_IndexParamVideoProfileLevelQuerySupported,
3185d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
3186f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        mIsLegacyVP9Decoder = err != OK;
3187f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    }
3188f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
319789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
319889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
319989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
320089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
32010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
320289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
320389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
320489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
32050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
320689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
320789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
32080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
320989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3215a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component input buffer number to be |tmp|. If succeed,
3216a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set input port buffer number to be |tmp|. If fail,
3217a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3218a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-input-buffers", &tmp)) {
3219a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexInput, tmp);
3220a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3221a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3222a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3223a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
3224a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component output buffer number to be |tmp|. If succeed,
3225a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set output port buffer number to be |tmp|. If fail,
3226a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3227a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-output-buffers", &tmp)) {
3228a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexOutput, tmp);
3229a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3230a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3231a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3232a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
323378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
323478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
323578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
323678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
323778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
323878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
323978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
324078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
324178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
324378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3256b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3257b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3258b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
32598338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
32608338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3261db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3262db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3263db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return err;
3264db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3265db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
32665e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
3267db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
3268db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        err = OK;
3269db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3271b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3272b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3273b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3274d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3275d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3276b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3277b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3278b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3279b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3280b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
32818338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3282b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3283b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3284b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3285d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3286b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3294b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3297b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3298b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3299b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3300db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting color aspects failed even though codec advertises support",
3301b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
33028338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
33038338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
33048338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3305b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3306b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3307b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
33088338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
33098338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3310b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
33118338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3312b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3313b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3314b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3315b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3316b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3317b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3318b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
33198338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33208338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3321b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
33228338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3323b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3324b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3325b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3326b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3328b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3329b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3330d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
33318338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3333b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3334b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3335b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3336b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3337b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3338b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3339b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3340b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3341b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3342b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3343b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3345b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3346b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3347b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3348b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
33498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3350b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3351b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3352b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3353b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3354b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3355b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3356b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3357b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
33588338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3360b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3361b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3362b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3363b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3364b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3365b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3367b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3368b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3369b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3377b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
33788338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3379b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3380b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3381b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3382b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3385b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3386b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3388b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3389b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3390b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3391b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3392b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3394b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3398b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
34058338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
34078338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3408b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3411b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3412b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3414b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3415b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
34168338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34178338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3418b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
34198338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
34208338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3424b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3425b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3427b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3434b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3435b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3436b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3437b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3439b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3440b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3441b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3442b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3443b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3444b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3445b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3446b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3447b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3448b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
34498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34508338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3451b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3452b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3453b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3454b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3455b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3456b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3457b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3458b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3459b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3460b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3461b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3462b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3463b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3464b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3465b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
34665e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::setHDRStaticInfoForVideoCodec(
34675e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
34685e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
34695e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34705e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    DescribeHDRStaticInfoParams params;
34715e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    InitOMXParams(&params);
34725e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
34735e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34745e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    HDRStaticInfo *info = &params.sInfo;
34755e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (getHDRStaticInfoFromFormat(configFormat, info)) {
34765e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
34775e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
34785e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34795e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    (void)initDescribeHDRStaticInfoIndex();
34805e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34815e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    // communicate HDR static Info to codec
34825e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    return setHDRStaticInfo(params);
34835e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang}
34845e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
3485b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3486b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3487b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
34888338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
34898338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3490b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
34918338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
34928338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3493b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3494b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3495b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3496b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3497b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
34988338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
35018338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3502b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3503b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3504b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3505b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3506b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3507b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3508b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3509b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
35128338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
35138338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
35208338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
35298338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35375e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
35385e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3539db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    DescribeHDRStaticInfoParams params;
3540db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    InitOMXParams(&params);
35415e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
3542db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3543db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = getHDRStaticInfo(params);
3544db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == OK) {
3545db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        // we only set decodec output HDRStaticInfo if codec supports them
3546db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, format);
3547db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3548db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3549db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3550db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3551db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::initDescribeHDRStaticInfoIndex() {
3552d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3553d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
3554db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3555db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
3556db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3557db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3558db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3559db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3560db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
3561db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3562db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3563d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3564db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3565db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3566db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    const HDRStaticInfo *info = &params.sInfo;
3567db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
3568db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
3569db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str(),
3570db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
3571db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
3572db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
3573db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
3574db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3575db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3576db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting HDRStaticInfo failed even though codec advertises support",
3577db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3578db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3579db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3580db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3581db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
3582db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3583db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3584d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3585db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3586db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3587db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3588db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] getting HDRStaticInfo failed even though codec advertises support",
3589db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3590db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3591db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3592db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
35938338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3594b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3595b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
35975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
35985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
35995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
36025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
36055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
36065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
36105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3623d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3624d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
36415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
36425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
36435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
36465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
36485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
36495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
36555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
36575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
36595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
36605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
36615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
36632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3668a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3669a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3670a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3671a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3672a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
36735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3674d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3675d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
36765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
36795778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
36805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3705d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3706d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3719d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3720d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3729870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3730870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3731870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3732870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3733870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3734870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3735870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3736870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3737870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3738870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3739870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
37405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
37435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
37515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3753c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3754c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3755c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3756c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
375789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
375889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
37599bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            err = setupVPXEncoderParameters(msg, outputFormat);
376089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
376189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37660f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
37670f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
37680f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
37690f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
37708338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
37718338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3772b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3773b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
37748338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
37758338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
37768338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
37778338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
37785e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err != OK) {
37795e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        return err;
37805e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
37815e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
37825e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
37835e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
37845e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
37855e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        err = OK;
37865e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
37875e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
37880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
37890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
37900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
37910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
37920f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    switch (compressionFormat) {
37930f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingAVC:
37940f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingHEVC:
37950f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat);
37960f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            if (err != OK) {
37970f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                err = OK; // ignore failure
37980f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            }
37990f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38000f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38010f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP8:
38020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP9:
38030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // TODO: do we need to support android.generic layering? webrtc layering is
38040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // already set up in setupVPXEncoderParameters.
38050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38060f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38070f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        default:
38080f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38090f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
38100f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
3811d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3812d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3813d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
38145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
38165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
38190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
38200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
38210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
38220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
38240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
38260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
38270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
38280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
38290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
38300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
38310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
38320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
38330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
38350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
38360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
38370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
38380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
38390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
38400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
38410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
38430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
38440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
38450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
38460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
38470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
38480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
3849d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
3850d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
38510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
38520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
38530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
3854f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnarstatic OMX_U32 setPFramesSpacing(
385563a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar        float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) {
3856f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // BFramesSpacing is the number of B frames between I/P frames
3857f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // PFramesSpacing (the value to be returned) is the number of P frames between I frames
3858f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3859f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1
3860f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                                     ^^^                            ^^^        ^^^
3861f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                              number of B frames                number of P    I frame
3862f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3863f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                  = (PFramesSpacing + 1) * (BFramesSpacing + 1)
3864f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3865f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // E.g.
3866f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //      I   P   I  : I-interval: 8, nPFrames 1, nBFrames 3
3867f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //       BBB BBB
3868f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
3869f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    if (iFramesInterval < 0) { // just 1 key frame
3870f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1
3871f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    } else if (iFramesInterval == 0) { // just key frames
38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3874f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
3875f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // round down as key-frame-interval is an upper limit
3876f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval);
3877f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1);
3878f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    return ret > 0 ? ret - 1 : 0;
38795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
388196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
388296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
388396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
388496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
388596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
388696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
388796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
388896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
388996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
38905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
389163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
389263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
389463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
38965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
389896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
389996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
39015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
39025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
39035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
39075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
39105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
39115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
39125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3913d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
3914d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
39155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
39225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
39235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3927f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nBFrames = 0;
3928f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames);
39295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
39315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
39335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
39345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
39355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
39365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
39375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
39385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
39415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
39425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
39475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
39495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
39505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
39535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
39545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3956d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3957d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
39585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
396396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
39705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
397363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
397463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
397663a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
39775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
39785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
398096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
398196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
39855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
39865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
39895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
39925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
39935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
39945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3995d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
3996d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
39975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
40035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
40045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4005f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nBFrames = 0;
4006f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames);
40075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
40085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
40095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
40125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
40135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
40145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
40155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
40165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
40195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
40215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
40225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
40255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
40265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
40295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
40305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
40315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
40325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4033d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4034d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
40355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
404096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
40415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
40475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4049a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
4050a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
4051a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
4052a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
4053a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
4054a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
4055a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
4056a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
4057a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
4058a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
4059a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
4060a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
4061a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4062a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4063a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
4064a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
4065a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
4066a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
4067a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
4068a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
4069a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4070a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
4071a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
4072a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
4073a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
4074a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
4075a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
4076a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
4077a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
4078a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
4079a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
4080a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
4081a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
4082a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
4083a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
4084a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
4085a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
4086a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
4087a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
4088a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
4089a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
4090a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4091a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
4092a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
4093a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
4094a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
4095a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
4096a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
4097a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4098a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
4099a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
4100a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
41015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
410263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
410363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
41045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
410563a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
41065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
41075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
410996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
411096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
41115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
41125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
41135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
41145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
41155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
41165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
41185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
41210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
41220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
41230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
41240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
41250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
41260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
41270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
41280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
41290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
41300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
41315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
41325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
41335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
41345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4135d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4136d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
41375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
41505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
41555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
41565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
4160e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else {
41618eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
41624c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#if 0   /* DON'T YET DEFAULT TO HIGHEST PROFILE */
41634c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar        // Use largest supported profile for AVC recording if profile is not specified.
4164826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        for (OMX_VIDEO_AVCPROFILETYPE profile : {
4165826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
4166826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            if (verifySupportForProfileAndLevel(profile, 0) == OK) {
4167826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                h264type.eProfile = profile;
4168826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                break;
4169826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            }
4170826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        }
41714c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#endif
41728eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    }
41738eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang
4174e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
4175e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            asString(h264type.eProfile), asString(h264type.eLevel));
4176e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang
41775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
41785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
41795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
41815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
4182f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
41835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
41845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
41855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
41875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
41885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
41895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
41915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
41925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
4194e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
4195e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
4196e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nSliceHeaderSpacing = 0;
4197e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
4198e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefFrames = 2;
4199e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nBFrames = 1;
4200f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4201e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nAllowedPictureTypes =
4202e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
4203e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
4204e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
4205e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
4206e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
4207e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bconstIpred = OMX_TRUE;
4208e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
4209e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
4210e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nCabacInitIdc = 1;
42115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
42145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
42155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
42185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
42195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
42205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
42215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
42225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
42235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
42245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4225d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4226d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
42275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
42305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4232e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering
4233e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering
4234e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // is preferred.
4235e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    AString tsSchema;
4236e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    int32_t preferBFrames = (int32_t)false;
4237e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    if (msg->findString("ts-schema", &tsSchema)
4238e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) {
4239e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
4240e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        InitOMXParams(&layering);
4241e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        layering.nPortIndex = kPortIndexOutput;
4242d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
4243d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
4244e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                        &layering, sizeof(layering)) == OK
4245e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.eSupportedPatterns
4246e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.nBLayerCountMax == 0) {
4247e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nBFrames = 0;
4248e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4249e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
4250e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            ALOGI("disabling B-frames");
4251d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(
4252d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4253e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
4254e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            if (err != OK) {
4255e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                return err;
4256e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            }
4257e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        }
4258e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    }
4259e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
426096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
42615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4263c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
426463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
426563a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
4266c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
426763a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4268c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
4269c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4270c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4271c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
4272c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4273c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
4274c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
4275c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
4276c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
4277c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4278c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4279c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
4280c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4281c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4282c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4283c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4284c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4285c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4286c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4287d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4288d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4289c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4290c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4291c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4292c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4293c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4294c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4295c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4296c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4297c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4298c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4299c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4300c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
4301c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4302c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4303c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4304c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4305c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4306c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4307c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
43089aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
4309f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
4310c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4311d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4312d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4313c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4314c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4315c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4316c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4317c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
4318c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4319c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
43209bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnarstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
432189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
432263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval = 0;
43234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
43244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
43254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
43264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
43274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
43284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
43294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
43304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
43314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
43324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
433389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
433489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
433589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
433663a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    msg->findAsFloat("i-frame-interval", &iFrameInterval);
433789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
433889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
433989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
43404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
43414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
43424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
43434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
43444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
43454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
43464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
43474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
43484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
43494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
43509bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType =
43519bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
43529bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar
43534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
4354f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numLayers = 0;
4355f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numBLayers = 0;
4356f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        int tags;
4357f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        char dummy;
4358f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
4359f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0) {
43604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
43619bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
4362f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers;
4363f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
4364f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                        &numLayers, &dummy, &numBLayers, &dummy))
4365f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && (tags == 1 || (tags == 3 && dummy == '+'))
4366f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
43674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4368f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            // VPX does not have a concept of B-frames, so just count all layers
43699bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4370f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers + numBLayers;
43714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
4372f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
43734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
4374f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS);
43754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
43764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
43774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
43784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
43794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
4380d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4381d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
43824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
43834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
43844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
43854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
4386f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
43874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
43884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
43894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
43904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
43914154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
43924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
43934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
43944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
43954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
43964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
43974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
43984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
43994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
4401d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
4402d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
44034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
44044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
44054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
44069bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
44079bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // advertise even single layer WebRTC layering, as it is defined
44089bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers));
44099bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsLayers > 0) {
44109bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid
44119bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers));
44124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
44144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
441589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
441689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
441789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
44185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
44195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
44205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
44215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
44225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
44235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44246e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
44256e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
4426d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
44275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
4428d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
44295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
44315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
44325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
44355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
44365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
44385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
44406e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
44416e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
44426e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
44436e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
44446e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
44456e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
44465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44476e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
44485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
445096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
445196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
44525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
44535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
44545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
44555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4456d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4457d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
44585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
44605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
44615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
446396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
44645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
44655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4466d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4467d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
44685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
44715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
44725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
44735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
44745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4475d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4476d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
44775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
44785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
44805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
44815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
44845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
44855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
44865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
44875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
44885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4489d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4490d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
44915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
44925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
449678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
449778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4504d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4505d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4506777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4507777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4508777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4518777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4519777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4520777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4521777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
452978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
453078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
453178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4534d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4535d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
4542d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        return mOMXNode->enableNativeBuffers(kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mOMXNode->enableNativeBuffers(kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4549d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4550d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4551d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4552d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4553d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4554d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4555d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4556d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4557d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4558d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4559d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4560d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4561d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4562d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
45637e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
45647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
45657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
45677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
45687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
45707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
45717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
45727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
45737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
45757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
45767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45777e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
45787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
45797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
45807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
45817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4582e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
45837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4584c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4585054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4586054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4587c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
45887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
45897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
45907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4598609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4627e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4628777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
462931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
463031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4631e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
463231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4633d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
4634777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4635777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4636777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
463731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4638777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4639777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4640777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4641777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
464231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
464331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
464431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
464531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
464631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4647e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4648e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4649e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4650e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4651e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4652e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4653e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4654e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4655e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4656e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
46570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
465873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
46590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
46600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
46610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
46620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
46630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
46640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
46650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
46660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
4667d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (DescribeColorFormat(mOMXNode, describeParams)) {
46680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
46690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
46700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
46710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
46720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
46735a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
467473dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
467573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
467673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
467773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
467873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
467973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
468073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
46810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
468203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
468303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4684b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4685b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4686b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4687b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4688b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4689b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4690b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4691b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4692d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (mOMXNode->getConfig(
4693b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4694b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4695b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4696b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4697b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4698b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4699b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4700b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4701b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
470291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4703b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4704b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4705b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4706b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4707b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4708b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4709b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4710b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4711b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4712b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
471331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4714b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4715b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4716b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4717b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4718b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4719b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4720b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4721b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4722b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4723b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4724b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4725b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4726b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4727b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4728b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4729b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4730b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
47315e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
4732b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4733b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
47345e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        if (mConfigFormat->contains("hdr-static-info")) {
47355e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                            (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
47365e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        }
4737777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4739e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4740e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
47414730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
47424730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
47434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
47444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
47454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
47464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
47474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
4748d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    status_t err = mOMXNode->getParameter(
47494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
47504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
47514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
47524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
47534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
47549bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                        if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC
47559bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount > 0
47569bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount
47579bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
47589bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            // advertise as android.generic if we configured for android.generic
47599bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            AString origSchema;
47609bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            if (notify->findString("ts-schema", &origSchema)
47619bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                    && origSchema.startsWith("android.generic")) {
47629bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
47639bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "android.generic.%u", vp8type.nTemporalLayerCount));
47649bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            } else {
47659bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
47669bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount));
47674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
47684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
47694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
47704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
47714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
47724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4775777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4776777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4777777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4778777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4779777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4780777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4781777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4782e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4783e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4784e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4785e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4786e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4787e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4788e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4789870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4790870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4791870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4792870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4793870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4794e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
479631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4797e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4798e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
47995a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
48005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
48015a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
48025a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
480331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
480431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
480531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
480631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
480731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
480831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
480931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
481097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4817d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4818d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioPcm, &params, sizeof(params));
4819777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4820777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4821777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
482214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4823777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4824777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4825777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
48265b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4827777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4828777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
48295b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
4830777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4831777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
48365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
48375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
48385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
48395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
48405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
48415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
48425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
48435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
48445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
48455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
48465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
48475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
48485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
48495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
48505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
48515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
4852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4854e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
48558b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
48578b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
48589806555d3930be43e11106281dee354820ac1c88Andreas Huber
4859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4860e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4861e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4862e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4865d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4866d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAac, &params, sizeof(params));
4867777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4868777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4869777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4870e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4877e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4878e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4879e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4881e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
48829806555d3930be43e11106281dee354820ac1c88Andreas Huber
4883d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4884d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAmr, &params, sizeof(params));
4885777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4886777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4887777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4888e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4889e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4890e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
48910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4892e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4893e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
48940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4895e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4896e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4897e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4898e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4899e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4900e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4901e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4902e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4903e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4905e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4906d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4907d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioFlac, &params, sizeof(params));
4908777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4911e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4912e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4913e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4914e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4915e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4916e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4917e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4918e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4919e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4920e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4921e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4923e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4924d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4925d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioMp3, &params, sizeof(params));
4926777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4927777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4928777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4929e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4930e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4931e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4932e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4933e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4934e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4935e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4936e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4937e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4938e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4939e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4940e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4941e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4942d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4943d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioVorbis, &params, sizeof(params));
4944777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4945777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4947e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4948e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4949e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4950e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4951e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4952e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4953e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
495497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
495597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
495697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
495797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4958e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
495997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4960d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4961d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4962777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4963777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4964777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4965777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
496697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
496797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
496897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
496997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
497097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
497197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4972e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
49738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
49748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
49758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
49768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
49778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
49788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4979d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4980d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4981777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4982777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4983777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
49858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
49878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
49888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
49898a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
49908a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
49918a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49928c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
49938c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
49948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
49958c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
49968c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
49978c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4998d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4999d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
5000777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5001777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5002777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5003777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
50048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
50058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
50068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
50078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
50088c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
50098c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
50108c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
501110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
501210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
501310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
501410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
501510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
501610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
5017d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5018d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
5019777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5020777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5021777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
502210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
502310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
502410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
502510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
502610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
502710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
502810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
502910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
503010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
503110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
503210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
503310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
503478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
503510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
503610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
503741d3f579d2c166984958263533284209b90c87d5Marco Nelissen
503841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
503941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
50400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
504141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
504241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
504341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
5044d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5045d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                OMX_IndexParamAudioPcm, &params, sizeof(params));
5046777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5047777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5048777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
504941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
505041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
505141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
50520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
505341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
505410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
505510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
5056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
5057777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
5058777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
5059777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
5060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
506131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
506231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
506331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
506431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
5065777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
5066777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
506731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
506831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5069e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
5070e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
5071e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5072b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
5073b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
5074b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
5075b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
5076b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5077b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
5078b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5079b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
5080b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5081b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5082b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
5083b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5084b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5085b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
5086b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5087b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5088b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5089b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5090b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
5091b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5092b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5093b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
5094b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5095b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5096b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
5097b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5098b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5099b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5100b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5101b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
5102b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
5103b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
5104b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5105b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
5106b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
5107b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
5108b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
5109b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
5110b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
51111734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5112697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // store new output format, at the same time mark that this is no longer the first frame
5113b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
5114e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5115b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5116777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5117777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
5118777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5119e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
51201734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    if (expectedFormat != NULL) {
51211734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
51221734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
51231734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        if (changes->countEntries() != 0 || to->countEntries() != 0) {
51241734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
51251734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mComponentName.c_str(),
51261734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    changes->debugString(4).c_str(), to->debugString(4).c_str());
51271734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        }
51281734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    }
51291734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar
51305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
51315b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
51325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
51335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
51345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
51355b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
51365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
51375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
51385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
51395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
51405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
51415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
5142b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
5143b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
5144b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5145b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5146b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5147b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> &notify) {
5148e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
5149b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5150e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5151b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) {
5152b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // notify renderer of the crop change and dataspace change
5153e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
5154b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t left, top, right, bottom;
5155b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
5156b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setRect("crop", left, top, right + 1, bottom + 1);
5157b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5158b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5159b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t dataSpace;
5160b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
5161b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setInt32("dataspace", dataSpace);
5162b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5163b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5164b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5165b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5166b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
5167b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
5168b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5169b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5170b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5171b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        int32_t channelCount, sampleRate;
517284d7e874983ee0d66db328c454fa603374d4635fMarco Nelissen        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5173b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
5174b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        if (mSampleRate != 0 && sampleRate != 0) {
5175b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderDelay = mEncoderDelay * sampleRate / mSampleRate;
5176b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderPadding = mEncoderPadding * sampleRate / mSampleRate;
5177b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mSampleRate = sampleRate;
5178b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        }
5179e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
5180e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
5181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
5182ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
5184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
5185b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
5187e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5188b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> notify = mNotify->dup();
5189b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
5190b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setMessage("format", mOutputFormat);
519131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
519231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5193b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5194b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
519531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
519631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51975778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5198cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
5199d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
5200251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5201251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
5202251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
5203251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
5204251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
5205251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
5206251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
5207251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5208251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5209251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5210346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5211346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
5212346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
52135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
5214251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
5215cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
5216cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5217cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5218496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5219496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5220496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5221496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5222496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5223496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5224496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5225496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5226496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5227496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5228496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5229d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setConfig(
5230496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5231496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5232496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5233496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5234496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
52357e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim////////////////////////////////////////////////////////////////////////////////
52367e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
52377e34bf5af26f8752d4786d3098740cdf51e2438fWonsik KimACodec::PortDescription::PortDescription() {
52387e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim}
52397e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
5240eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
52414811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        IOMX::buffer_id id, const sp<MediaCodecBuffer> &buffer) {
5242eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
5243eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
5244eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5245eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5246eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
5247eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
5248eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5249eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5250eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
5251eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
5252eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5253eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
52547e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimsp<MediaCodecBuffer> ACodec::PortDescription::bufferAt(size_t index) const {
5255eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
5256eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5257eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5258eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
5259eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5260f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5265ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5266ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
528426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
528526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
528626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
528726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
528826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5289e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5290e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5291e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5292e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5293e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5294e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
529726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
53011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
53021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
53031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
53041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
53061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
53071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53082235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
53091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
53111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
53121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
53131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
53141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
53151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
53178f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
53187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
53197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5320251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
53217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
53227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
53237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
53247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
53257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5326ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5327ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5328251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5329ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
53306d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            mCodec->mGraphicBufferSource.clear();
5331ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5332ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5333ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5334ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
533530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
533630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
533730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
533830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
5339d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->freeNode();
534030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
534130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
534230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
534330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
534430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
534530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
534630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
534730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
535526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
53565e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
53575e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5358d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode == NULL) {
53595e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
53605e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
536126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
53625e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
53635e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5364d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    int32_t generation;
5365d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(msg->findInt32("generation", (int32_t*)&generation));
5366d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (generation != mCodec->mNodeGeneration) {
5367d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        ALOGW("Unexpected message for component: %s, gen %u, cur %u",
5368d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
5369777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5370777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
537126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
537226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
537326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
537426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
537526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
537626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
537726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
537826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
537990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
538026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
538126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5382e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5383e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
538490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
538590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
538690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
538790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
538890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
538990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
539090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
539190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
539290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
539390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
539426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
539526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
539626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
539726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
539826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
539926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
540026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54100af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
54110af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
54120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
54130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
54140af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
54150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
54160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
54170af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
54180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
54190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
54200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
543015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
543115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5432609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
543315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5441609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
545015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
545615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
545715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
546090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
546190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
546290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
546390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
546490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
546590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
546690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
546790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
546890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
546990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
547090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5472777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5473777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
547790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
547890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
547990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
548090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
548190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
548290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5485b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
54866cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang        ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
5487b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5488b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5489b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5490b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5491b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5493ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5499ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5501251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5502251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5503251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5504251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5505251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5506251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5507251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5513ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5514349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5515349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
55160806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
55170806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
55180806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
55190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
55200806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
552115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
552215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
552315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
55240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
55250806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
552815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
552915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
553015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
553115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
553215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
553315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
553415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
553596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
553696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
553796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
553896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
553996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
554096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5541d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5552777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5554777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5555777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
5569d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
5570609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
55737e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    notify->setObject("buffer", info->mData);
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
5576609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
5577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
5581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5587609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
55887e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
55905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5591a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
55925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55937e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<RefBase> obj;
55947e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    if (!msg->findObject("buffer", &obj)) {
5595a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55987fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
55997fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
56007fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
56017fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
56027fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
56037fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
56047fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
56057fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
56063831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
56072d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
56087e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    } else {
56097e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer = static_cast<MediaCodecBuffer *>(obj.get());
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
56135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
56145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
56155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
56165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
56175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
56190806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
56200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
56210806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
56220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
56230806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
56240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
56250806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5633dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5634dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5635dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5636dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5644fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5645fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5646fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5647fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5648fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5649fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5655d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                MetadataBufferType metaType = mCodec->mInputMetadataType;
5656d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                int32_t isCSD = 0;
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5658f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    if (mCodec->mIsLegacyVP9Decoder) {
5659f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
5660f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                            mCodec->mComponentName.c_str(), bufferID);
5661f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        postFillThisBuffer(info);
5662f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        break;
5663f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    }
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5665d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    metaType = kMetadataBufferTypeInvalid;
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
56695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
56705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
56715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
56725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (buffer != info->mCodecData) {
5673ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5674d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5675d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
56765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                         buffer.get(), info->mCodecData.get());
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
5679d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (converter == NULL || isCSD) {
56805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
56815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
56825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
56835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
56845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
56850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
56860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5689078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5690ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5691078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
56925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5693ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
56945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5695078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5696d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5697ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5698ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5699d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5700ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5701ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5702d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5703078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5704349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5705d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5709d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5710d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5711d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5712054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5713054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5714054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5715054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5716054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5717054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5718054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5719054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5720054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5721054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
572415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5725d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5726d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                status_t err2 = OK;
5727d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                switch (metaType) {
5728d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeInvalid:
5729d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5730d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5731d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeNativeHandleSource:
5732d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
5733d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeHandleMetadata *vnhmd =
5734d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            (VideoNativeHandleMetadata*)info->mCodecData->base();
5735d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        err2 = mCodec->mOMXNode->updateNativeHandleInMeta(
5736d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                mCodec->kPortIndexInput,
5737d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                NativeHandle::create(vnhmd->pHandle, false /* ownsHandle */),
5738d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                bufferID);
5739d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5740d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5741d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                case kMetadataBufferTypeANWBuffer:
5742d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
5743d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
5744d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        err2 = mCodec->mOMXNode->updateGraphicBufferInMeta(
5745d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                mCodec->kPortIndexInput,
5746d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                new GraphicBuffer(vnmd->pBuffer, false /* keepOwnership */),
5747d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                                bufferID);
5748d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5749d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5750d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#endif
5751d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                default:
5752d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
5753d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            asString(metaType), info->mCodecData->size(),
5754d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            sizeof(buffer_handle_t) * 8);
5755d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    err2 = ERROR_UNSUPPORTED;
5756d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5757d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
5758d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5759d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                if (err2 == OK) {
5760d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err2 = mCodec->mOMXNode->emptyBuffer(
5761d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        bufferID,
5762d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        0,
5763d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        info->mCodecData->size(),
5764d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        flags,
5765d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        timeUs,
5766d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        info->mFenceFd);
5767d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
576815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
57690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
57700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
57710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
57720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
57765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
57775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
57780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
57790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
57805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
57825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
57835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
57850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
57860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5787dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5788dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
57893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5790dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5791dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5793ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5794349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5795349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
579615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5797d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                status_t err2 = mCodec->mOMXNode->emptyBuffer(
57980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
57990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
58000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
58010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
580215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
580315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
580415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
58050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
58060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
58070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
58080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5812dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5816625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5817777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5818777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5819777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5820625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5821777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5822625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
585915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
586015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5861609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
58625778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5863349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
58650806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5866d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5867d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5868d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5869d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5870d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5871d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5872d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5873d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5874d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5875d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5876d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5877d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5878d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5879d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5880d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5881d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
58840806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
58850806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
58860806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
58870806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
58880806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
588915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
589015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
589115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
58920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
58930806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
589890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
589990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
590090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
590190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
590290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
590390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
590490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
590590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
590690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
590715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
590815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
590915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
591015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
591115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
591215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
591315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5922a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5923a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5924609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
59255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5926349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5927d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mCodec->mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
592815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
59290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
59300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
59320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
59355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
59365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
593731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5938577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
59391d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
59407e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            sp<MediaCodecBuffer> buffer = info->mData;
5941577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5942b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5943697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                // pretend that output format has changed on the first frame (we used to do this)
5944697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
59451734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
5946697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                }
5947b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
5948b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
5949fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            } else if (rangeLength > 0 && mCodec->mNativeWindow != NULL) {
5950fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                // If potentially rendering onto a surface, always save key format data (crop &
5951fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                // data space) so that we can set it if and once the buffer is rendered.
5952fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
59535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5954b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5955054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
5956054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
59573e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                VideoNativeHandleMetadata &nativeMeta =
59587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    *(VideoNativeHandleMetadata *)buffer->data();
59597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                if (buffer->size() >= sizeof(nativeMeta)
59603e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeNativeHandleSource) {
59617c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
59623e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    // handle is only valid on 32-bit/mediaserver process
59637c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
59647c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
59653e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    handle = (native_handle_t *)nativeMeta.pHandle;
59667c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5967054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
59687e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setPointer("handle", handle);
59697e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeOffset", rangeOffset);
59707e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeLength", rangeLength);
59717e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            } else if (buffer == info->mCodecData) {
59727e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->setRange(rangeOffset, rangeLength);
59735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
59745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
59755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
59765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
59777e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                        info->mCodecData, buffer);
59785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
59795b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
59815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
5982308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
5983496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
598421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
5985496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
5986496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
5987496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
59885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
598921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
5990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
59927e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                mCodec->mSkipCutBuffer->submit(buffer);
59938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
59947e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            buffer->meta()->setInt64("timeUs", timeUs);
5995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5997d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5998609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
59997e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            notify->setObject("buffer", buffer);
60005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6002609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
60075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
60085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
60115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
60125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
6014d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
6015dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6023777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
60240806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
60250806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
60260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
60280806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6030777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6031777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6032777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6033777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
6041609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
60427e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<RefBase> obj;
60437e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer = nullptr;
60447e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    if (msg->findObject("buffer", &obj)) {
60457e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer = static_cast<MediaCodecBuffer *>(obj.get());
60467e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    }
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
60480806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
60490806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
60500806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
60510806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
60520806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
60530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
60540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
60550806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6057577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
6058fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)
6059fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            && memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
6060fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar        mCodec->mLastNativeWindowCrop = crop;
6061777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
6062777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
6063577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
6064577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
6065b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t dataSpace;
6066fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    if (msg->findInt32("dataspace", &dataSpace)
6067fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            && dataSpace != mCodec->mLastNativeWindowDataSpace) {
6068b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = native_window_set_buffers_data_space(
6069b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
6070fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar        mCodec->mLastNativeWindowDataSpace = dataSpace;
6071b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
6072b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6073b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
60766aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
60777e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            && buffer != NULL && buffer->size() != 0) {
60786fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
608190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
608290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
60837e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
608490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
608590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
608690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
608790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
608890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6089fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
6090fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
6091c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
60927e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
6093c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
6094fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
6095fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
6096fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
6097fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
60985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
6099fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
61000806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
6101fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
610215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
61030806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
610415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
610515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
61060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
6107cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
6108cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
6109264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
6110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6111cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
611215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
611315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
6114cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
6115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
61166fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
61177e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            (buffer == NULL || buffer->size() != 0)) {
611815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
611915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
61206fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
61216fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
6122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
6123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
6149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6151c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
6152609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
6153c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
615415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
6155d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    status_t err = mCodec->mOMXNode->fillBuffer(
6156d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            info->mBufferID, info->mFenceFd);
615715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
61580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
61590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
61600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
61610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
61620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
6163c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6168777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
61700806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
61710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
61720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
61730806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6176777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6177777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6178777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6179777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6185f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
6186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
6190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
6191ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6192ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
61931d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        if (mCodec->mOMXNode != NULL) {
61941d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang            sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
61951d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang            binder->unlinkToDeath(mDeathNotifier);
61961d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        }
6197ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
6198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
6199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6200b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
6201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
6202e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
6203ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
6204d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode.clear();
6205ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6206054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
6207054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
62085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
62095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6210ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6213f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
62265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
62275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
62285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
62295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
62305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
62315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6234c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
623754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
623854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
6239c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6241d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
6242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6245c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6251d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6255c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
625830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
625930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
626030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
626130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
626230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
626330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
626430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6272f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
62785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
62795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
62815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
62825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6283d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode == NULL);
62845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
628648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
628748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
628848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
628948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
6290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6294ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6295b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
62965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
6300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
63017791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
63025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6303b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6304b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6305b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6306afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
63075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
63085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
63095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
63105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
63115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
63125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
63135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6314b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
63155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
63165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6317b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6318e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
63195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
63201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
63211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6322d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
63231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6324201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
63251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
63261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6327b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6328b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6330da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6331078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6332078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
63331d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
6334078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
63371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
63387a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
63397a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
63401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
63411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6342d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode = NULL;
63431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
63441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6345d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (omxNode == NULL) {
63465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
63479f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
63489f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
63495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
63509f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
63515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6352c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
635352e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6355c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
635723858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
63581d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang    if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
635923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // This was a local binder, if it dies so do we, we won't care
636023858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // about any notifications in the afterlife.
636123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mDeathNotifier.clear();
636223858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
636323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
636426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6365d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    notify->setInt32("generation", ++mCodec->mNodeGeneration);
6366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
636990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6370ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6371ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6372ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6373ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
63741713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
63750167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6376ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6377ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
637821b46588d022d0c22d7c7c08e919d7a9c5cd76e3Chong Zhang    omxNode->setQuirks(quirks);
6379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6380d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode = omxNode;
6381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
63835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6384d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
63855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
63865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
63875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6388c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6391c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
63925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
63935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6394c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6395c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6396c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6397c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6403f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6404f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6405f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6406f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6407f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6408054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6409054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6410a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6411e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6412e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
64134e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
64146d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    mCodec->mGraphicBufferSource.clear();
6415054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6416c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6417c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6418c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6420c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6421c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6422c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6423c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
642454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6425f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6426f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
6431d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        (void)mCodec->mOMXNode->freeNode();
6432c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6433c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6434c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6435c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
643654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
643754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
6438d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
643954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
644054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
644154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6443c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
64557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
64567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
64577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
64587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
64597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
64607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
64617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
64628f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6463d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
64648f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6465d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6466d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6467d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6468d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6473c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6474c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6475c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6476c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6477c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6478c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
648254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6484c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6485c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6486c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6487c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6488c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6489c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6490c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6491c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6492d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
6494c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6496c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6501c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6504c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6506c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
65075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
65085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
65095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6510d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode != NULL);
65115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
65120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
65135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
65140806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
65150806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
65160806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
65170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
65180806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
65195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6520c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6521c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6522c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6523251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6524c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
65255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
65285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6529d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
6530e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
6531e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
65325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
65335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6535c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
65365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
65375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6538d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6539addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (mCodec->mGraphicBufferSource == NULL) {
6540addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return BAD_VALUE;
6541addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6542addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6543addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    android_dataspace dataSpace;
6544addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err =
6545addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6546addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != OK) {
6547addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Failed to get default data space");
6548addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
6549addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6550addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6551addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    err = statusFromBinderStatus(
6552addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace));
6553addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != OK) {
6554addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("[%s] Unable to configure for node (err %d)",
6555addf2cbb120346ae42e78fa739245a353db5edadChong Zhang              mCodec->mComponentName.c_str(), err);
6556addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
6557addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6558a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6559d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
65606d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65616d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
65626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mRepeatFrameDelayUs));
6563a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6564a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6565a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6566a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
65676d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6568d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6569a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6570a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6571a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6572d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
65736d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65746d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setMaxTimestampGapUs(
65756d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mMaxPtsGapUs));
657694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
657794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
657894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
65796d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6580d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
65812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
65822c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
65832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6584d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
65856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65866d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
658737b2b389139ed638831e49708c947863eef631efRonghua Wu
658837b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
658937b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
65906d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6591d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
659237b2b389139ed638831e49708c947863eef631efRonghua Wu        }
659337b2b389139ed638831e49708c947863eef631efRonghua Wu    }
659437b2b389139ed638831e49708c947863eef631efRonghua Wu
6595d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
65962c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
65976d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setTimeLapseConfig(
65996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mTimePerFrameUs, mCodec->mTimePerCaptureUs));
66002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
66012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
66022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
66036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6604d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
66052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
66062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
660772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6608d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
66096d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setSuspend(true));
661172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
661272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
661372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
66146d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6615d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
661694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
661794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
661894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6619c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6620d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode->getParameter(
6621d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6622c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6623c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6624c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6625c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6626c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6627b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6628b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
66296d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
66306d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
66316d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
66326d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
66336d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66346d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
66356d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        *(ColorAspects *)colorAspectsBuffer->base())));
66366d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
6637b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6638b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6639b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6640b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6641b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6643d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6644d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6645d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6646d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6647d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6648d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6649d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6650d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6651d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
6652d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6653d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6654addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = mCodec->mOMX->createInputSurface(
6655addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            &bufferProducer, &mCodec->mGraphicBufferSource);
6656d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6657d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6658d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6659d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6660d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
66617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
6662addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
6663addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6664addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        notify->setMessage("input-format", mCodec->mInputFormat);
6665addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        notify->setMessage("output-format", mCodec->mOutputFormat);
6666addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
66677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
66687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
66697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
66707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
66717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
66727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
66737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
66747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
66757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
66767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
66777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
66787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
66797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
66808f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
6681d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
66828f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6683d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6684d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6685d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
6686d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6687d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6688d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6689d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6690addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    mCodec->mGraphicBufferSource = surface->getBufferSource();
6691d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6692addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = setupInputSurface();
6693b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6694b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
66953e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar        mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
6696d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6697addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        notify->setMessage("input-format", mCodec->mInputFormat);
6698addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        notify->setMessage("output-format", mCodec->mOutputFormat);
6699addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    } else {
6700d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6701d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6702d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
67038f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6704d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
6705d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
6706d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6707d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
6708d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6709d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6710c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
67115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
67125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6713d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
67140806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
67150806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
67160806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
67170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
67180806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6723f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6727f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
67283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6730cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6731cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
673229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6733cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6734cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6735cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6736251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
673791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6738d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mCodec->mOMXNode->sendCommand(
6739d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
6740c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6741c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6742c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6743c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6744c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6745c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6746c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
674791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6748cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6751f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
6759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
676372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
67716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
67726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
67736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
67746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
67756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
67766463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
67776463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
67786463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
67796463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
67806463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
67816463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
67826463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
67836463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
67846463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
67856463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
6786d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
67876463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
67886463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
67896463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
67906463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6796f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
68010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
68020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
68030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
68040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
68050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
68060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
68070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
68080806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68100806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
6811d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mCodec->mOMXNode->sendCommand(
6812d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateExecuting);
68130806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68150806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
68160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
68170806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
68180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
68190806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6831f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6835f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
68363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6839f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
684172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6848d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6849d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6850d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6851d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6852d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6853d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6854d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6855d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6856d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
6857d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6858d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6859d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
6860d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6861d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6862d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6863d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
68646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
68656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
68666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
68676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
68686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
68696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6875f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
68800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
68810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
68820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
68830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
68840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
68850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
68870806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6902f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6903349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6904349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6907f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6908ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6913054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6914054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6915054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6918054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6919054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6920054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6921054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6922054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
69234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
69244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6925054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
69290806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
69340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
69350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
69360806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
69370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
69380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
69390806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
69450806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
69460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
69470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
69480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
69490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69520806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6953349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
695415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
6955d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mCodec->mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
695615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
69570806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
69580806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
69590806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
69600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
69640806340688c937e7b78c2d89db3809274130df4eLajos Molnar
69650806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
69660806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69670806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6971c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6972054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6976054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6977f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6978349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
69790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6980349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6981349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6982349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69853cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6986777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6987777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6988777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6989777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
69903cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
69913cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
69923cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
69933cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
69943cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
69953cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6996349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6997349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7000f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
70013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
7002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
7004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
7005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7007f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
7008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
7014c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
7015c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
7016c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
7017c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
701854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
7019c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
7020c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
7021349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
7022349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7023d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(
7024d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateIdle);
70250806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
70260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
70270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
70290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
70300806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
70310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
70320806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
70407a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
7041ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
7042d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
7043d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
7044d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
7045d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
7046d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
7047d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7048349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
7049349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7050d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
70510806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
70520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70530806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
70540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
70550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
7062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
7064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7069496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
7070496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
7071496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
7072496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
7073496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
7074496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
7075496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7076496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
7077496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
7078496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
7079496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7080a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
7081a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
7082a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
7083a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
7084a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7085a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
7086a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7087a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
7088a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
7089a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
7090a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
7091a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
7092a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7093a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
7094a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
7095a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7096a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
70977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
70987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
70996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
71007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
71017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
71027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
71037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
71044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7105054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
71064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
71074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
71084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
7109054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
71104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
7111054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
71124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
71134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
71144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
71154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
71164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
7117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7125a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
7126a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
7127530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
7128a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7129a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
7130a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
7131a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
7132a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7133d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->setConfig(
7134a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
7135a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
7136a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
7137a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7138a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
7139a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7140a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
7141a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7142a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
7143a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7144a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
7145a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
714661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    int64_t timeOffsetUs;
714761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
71486d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
71496d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set input buffer time offset without surface",
71506d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
71516d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
71526d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
71536d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
71546d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
71556d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
715661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
715761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        if (err != OK) {
715861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            ALOGE("[%s] Unable to set input buffer time offset (err %d)",
715961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                mComponentName.c_str(),
716061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                err);
716161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            return err;
716261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
716361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    }
716461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
716572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
716672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
71676d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
71686d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set start time without surface",
71696d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
71706d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
71716d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
71726d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
71736d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
71746d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
717572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
717672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
717772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
717872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
717972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
718072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
718172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7182e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
7183e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
71846d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
71856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set suspend without surface",
71866d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
71876d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
71886d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
7189e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
71906d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
71916d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setSuspend(dropInputFrames != 0));
7192b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7193b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7194b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7195b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7196b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7197b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
7198b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7199b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7200b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7201b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7202b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7203b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7204b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7205b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7206b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7207e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7208e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
72098db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
72108db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
72118db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
72128db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
72138db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
72148db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
72158db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
72168db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
72178db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7218870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7219870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7220870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7221870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7222870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7223870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7224870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7225870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7226870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7227870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7228870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
72290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
72300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
72310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        err = OK; // ignore failure
72320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
72330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
72340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    return err;
7235a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7236a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
72376507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
72386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
7239d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
72406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
72416d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err = INVALID_OPERATION;
72426d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (mGraphicBufferSource != NULL) {
72436d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
72446d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
72456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
72466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
72476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
72486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
72496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
72506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
725190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
725290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
725390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
725490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
725590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7256f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7263b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7264b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
726531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7266054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7267d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                CHECK_EQ(mCodec->mOMXNode->sendCommand(
7268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7271349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7274b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7275b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7276ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7295f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7300f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7311f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7319e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7321349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
73223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7324349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7338f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
73393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
734390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
734490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
734590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
734690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
734790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
734890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
73550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
73560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
73570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
73580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
73630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
73640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
73650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
73660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
73670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
73680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
73690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
7372d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mCodec->mOMXNode->sendCommand(
7373d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_CommandPortEnable, kPortIndexOutput);
73740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
73770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
73780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
73790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
73800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7381cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
73820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7383251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7384d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7385755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7386755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7387755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7388755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7389755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7390755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7391755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7392755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7393cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7397777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7398777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7399777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7400777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7404349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7405349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7406349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7407349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7423f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
74245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
74255778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7428f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
74360806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7456f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
74573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
745831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
74595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7460b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7463f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
74680806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
74690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
74700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
74710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
74720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
74730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
74740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
74750806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
74785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7484349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7485349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7486349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7487349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7488349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7489349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7490349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
74950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7496f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
74975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
7498d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mCodec->mOMXNode->sendCommand(
7499d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
75000806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
75010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
75020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
75030806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
75040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
75050806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
75060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75080167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
75090167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7510bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7511bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7512bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7513bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7514b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7515bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7516bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
75170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
75180806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
75190806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
75200806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
75210806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7526f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7533f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7542f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7546f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
75620806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7574f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
75753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7578f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
75830806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
75840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
75850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
75860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
75870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
75880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
75890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
75900806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7604f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7608f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
76093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7614f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7639f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
7640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7641ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
7642ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
7643d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
76470806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
76480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
76490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
76500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
76510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
76520806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
7655777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
7656777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
7657777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
7658777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
7659777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
7661e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
76620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
7663e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
7664e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
7665777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
7666777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
7667777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
7668777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
7669777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
7670777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7671777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
7674777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
7675777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
7676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7681349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7682349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
76831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
7684349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
7685d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            msg->setInt32("generation", mCodec->mNodeGeneration);
7686349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
7687349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
7688349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
7689349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
76903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
7691349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
7692349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7693349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
7694349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7695349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7696349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7697349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
7703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7705f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
7706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7711f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
7712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7717f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
7718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
7719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
7720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
77217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
77227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
77237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
77247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
772590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
772690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
7728d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
7729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
7730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
7732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
7733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7734dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
7735dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
7736f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
7737f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
7738f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
7739f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
7740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
7741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
77455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
77465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
77475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
77481ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime.c_str());
77495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
77505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
77515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
77545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = client.connect();
77555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
77565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
77575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
77605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
7761d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
77625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77631d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang    err = omx->allocateNode(name.c_str(), observer, &omxNode);
77645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
77655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
77665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
77675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7769d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = SetComponentRole(omxNode, role);
77705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
7771d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode->freeNode();
77725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
77735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
77745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
77775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
77785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
77805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
77815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
77825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
77835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77846e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
77856e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
7786d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7787d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoProfileLevelQuerySupported,
77885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
77895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
77905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
77915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
77925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
77936e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
77946e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
77956e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
77966e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
77976e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
77986e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
77995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
78025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
78035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
78045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
78055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
780636e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
78075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
78086e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
78096e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
7810d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7811d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoPortFormat,
78125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
78135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
78145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
78155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
78165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
78181ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim            if (IsFlexibleColorFormat(
7819d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
78205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
78215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
78225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
78235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
78245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
78255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
78265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
78275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
78285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
78295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
78305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
78315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
78325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
78335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
78345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
78356e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
78366e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
78376e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
78386e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
78396e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
78406e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
78415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
78435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
78445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
78455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
78465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
78476e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
78486e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
7849d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7850d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
78515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
78525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
78535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
78545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
78555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
78565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
78576e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
78586e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
78596e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
78606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
78616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
78626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
78635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
78665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
78675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
78685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
78695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
78715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
78735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
7874d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->configureVideoTunnelMode(
7875d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
78765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
78775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
78785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
7879d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        } else if (omxNode->storeMetaDataInBuffers(
7880d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE) == OK ||
7881d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                omxNode->prepareForAdaptivePlayback(
7882d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE,
78835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
78845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
78855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
78875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
78895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
78905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
78915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
78925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
7893d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->getConfig(
7894d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
78955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
78965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
78975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
78995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
79005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
7901d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    omxNode->freeNode();
79025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
79035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
79045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
79055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7906a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
7907a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
7908a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
7909a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
7910a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
7911a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
7912a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
7913a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7914a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
7915a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7916a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7917a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7918a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
7919a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7920a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7921a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7922a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7923a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
7924a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7925a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7926a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
7927a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
7928a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7929a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
7930a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7931a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7932a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7933a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
7934a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
7935a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7936a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
7937a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7938a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7939a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7940a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7941a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7942a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7943a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7944a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
7945a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7946a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7947a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7948a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7949a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7950a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7951a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
7952a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7953a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
7954a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7955a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7956a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7957a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7958a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7959a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7960a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
7961a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
7962a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7963a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
7964a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
7965a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
7966a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7967a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
7968a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
7969a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
7971