ACodec.cpp revision 22dc508717c7767927064ec7c152def99e54adcb
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>
473fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang#include <media/OMXBuffer.h>
48ac7d4125516299b8a3e6f2b25822a692bdd96311Pawin Vongmasa#include <media/omx/1.0/WOmxNode.h>
493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
508a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa#include <hidlmemory/mapping.h>
518a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
5297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
56777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
59dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/ACodecBufferChannel.h"
605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar#include "include/DataConverter.h"
614811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim#include "include/SecureBuffer.h"
627e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include "include/SharedMemoryBuffer.h"
6373dd808754c641fe798273d356ee38368715fa7bLajos Molnar#include "omx/OMXUtils.h"
64496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6513a926879249276771b0097538459c7550e2f5ceSteven Moreland#include <android/hidl/allocator/1.0/IAllocator.h>
668a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa#include <android/hidl/memory/1.0/IMemory.h>
678a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
68f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
706d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangusing binder::Status;
716d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
726e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnarenum {
736e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
746e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar};
756e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
99251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
100251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
101251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
102251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
103251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
1056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangstatic inline status_t statusFromBinderStatus(const Status &status) {
1066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (status.isOk()) {
1076d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return OK;
1086d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1096d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err;
1106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.serviceSpecificErrorCode()) != OK) {
1116d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1126d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1136d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.transactionError()) != OK) {
1146d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1156d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1166d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Other exception
1176d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return UNKNOWN_ERROR;
1186d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
1196d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
132251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
13326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
13426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
13526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
136984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    virtual ~MessageList() {
137984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    }
13826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
13926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
14026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
14126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
14226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
14326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
14426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
1455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnarstatic sp<DataConverter> getCopyConverter() {
1465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
1475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static sp<DataConverter> sCopyConverter;        // zero-inited
1485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
1495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return sCopyConverter;
1505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar}
1515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
161984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        if (messages.empty()) {
162984a54322f7c70bc75e862d91bdd975814872affLajos Molnar            return;
163984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        }
164984a54322f7c70bc75e862d91bdd975814872affLajos Molnar
165984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        sp<AMessage> notify = mNotify->dup();
16626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
16726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
16826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
16926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
17226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
17326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
17426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
17526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
17626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
17726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
17826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
17926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
18026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
18326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
18426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
18526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
18626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
18726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
19026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
19126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
19326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
19526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
19626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
19826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
19926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
20026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
20126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
20226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
20326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
20426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
20526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
20626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
20726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
20826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
21190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
21290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
21390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
21490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
21590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
21690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
21790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
21890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
21926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
22026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
22126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
22226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
22326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
22426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
22526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
22626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
241090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
26426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
26826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
26926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
27026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
27126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
27226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
27315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
27915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
28015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
28390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2918a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasastruct ACodec::DeathNotifier :
2928a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        public IBinder::DeathRecipient,
2938a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        public ::android::hardware::hidl_death_recipient {
294090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit DeathNotifier(const sp<AMessage> &notify)
295ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
296ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
297ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
298ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
299ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
300ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
301ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3028a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    virtual void serviceDied(
3038a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            uint64_t /* cookie */,
3048a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
3058a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        mNotify->post();
3068a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    }
3078a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
308ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
309ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
310ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
311ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
312ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
313ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
314ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
315ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
316ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
318090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit UninitializedState(ACodec *codec);
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
322c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
329ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
336090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedState(ACodec *codec);
337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
340c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
343c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
345c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3478f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
350c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
351d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
352d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
355c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
356c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
359090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedToIdleState(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    status_t allocateBuffers();
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
375090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToExecutingState(ACodec *codec);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
389090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingState(ACodec *codec);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
392054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
400349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
401349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
40890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
411349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
412349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
419090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit OutputPortSettingsChangedState(ACodec *codec);
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
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);
42790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
436090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingToIdleState(ACodec *codec);
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
458090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToLoadedState(ACodec *codec);
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
473090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit FlushingState(ACodec *codec);
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
49515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
49615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
49715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
49815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
49915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
50015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
50115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
50215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
50315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
50415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
50515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
50615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
50715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
50915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
51015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
51115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
51215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
51315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
51415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
51515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
51615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
51715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
51815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
51915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
52015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
52115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
52215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
52315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
52415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
52515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
526f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
527b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    : mSampleRate(0),
528d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang      mNodeGeneration(0),
529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
530e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
531fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
5328db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
534346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5359806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
53654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
537f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang      mIsLegacyVP9Decoder(false),
5389806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5399806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
540e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5419806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
542054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
543054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
544054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
54694ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
54837b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
54922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa      mFps(-1.0),
55022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa      mCaptureFps(-1.0),
551ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
55289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang      mLatency(0),
5538338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
554db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
55501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
55601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar      mVendorExtensionsStatus(kExtensionsUnchecked) {
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
571dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
574d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
575d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
576fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
577fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
5798a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
5809c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    mTrebleFlag = false;
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
583f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
586f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5881d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
592dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstd::shared_ptr<BufferChannelBase> ACodec::getBufferChannel() {
593dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (!mBufferChannel) {
594dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel = std::make_shared<ACodecBufferChannel>(
595dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                new AMessage(kWhatInputBufferFilled, this),
596dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                new AMessage(kWhatOutputBufferDrained, this));
597dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
598dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    return mBufferChannel;
599dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
600dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
601a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
6021d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
603a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
604a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
605a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
606a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6075778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
6091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6135778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
6151d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
6201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
6211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
6221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
6241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
6251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
6271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
6281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
6331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
6347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6368f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
637d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
6388f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
639d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
640d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
641d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
642d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6475778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
651f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6527a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6531d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
656f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
66430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
66530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6661d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
66730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
670496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
672496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
673496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6754dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
679054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6804dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
681054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
682054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6834dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6844dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
696e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
7001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
7031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
7041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
7051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
715e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
716098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    // no need to reconnect as we will not dequeue all buffers
717098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(
718d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            nativeWindow, &usageBits, !storingMetadataInDecodedBuffers());
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
723f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
724e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
725e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
726e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
727e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
728e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
729e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
7361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
7391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
7451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
759dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
760dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
761dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
767054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
769598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa            ALOGV("skipping buffer");
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
784d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (!storingMetadataInDecodedBuffers()) {
7851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
78615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
79015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
79115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
8001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
8011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
8021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
804484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
805484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
806484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
807484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
808484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
8091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
810e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
8111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
8121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
814d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhangstatus_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
815d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    status_t err = mOMXNode->setPortMode(portIndex, mode);
816d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK) {
817d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
818d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                mComponentName.c_str(),
819d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                portIndex == kPortIndexInput ? "input" : "output",
820d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                asString(mode),
821d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                err);
822d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        return err;
823d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    }
824d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
825d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[portIndex] = mode;
826d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    return OK;
827d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang}
828d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8328a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    if (getTrebleFlag()) {
8338a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        CHECK(mAllocator[portIndex] == NULL);
8348a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    } else {
8358a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        CHECK(mDealer[portIndex] == NULL);
8368a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    }
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
841d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (storingMetadataInDecodedBuffers()) {
842054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
852d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
855d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            const IOMX::PortMode &mode = mPortMode[portIndex];
8565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
857d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // Always allocate VideoNativeMetadata if using ANWBuffer.
858d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // OMX might use gralloc source internally, but we don't share
859d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // metadata buffer with OMX, OMX has its own headers.
860d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mode == IOMX::kPortModeDynamicANWBuffer) {
861054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
862d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            } else if (mode == IOMX::kPortModeDynamicNativeHandle) {
8633e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                bufSize = sizeof(VideoNativeHandleMetadata);
864054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
865054219874873b41f1c815552987c10465c34ba2bLajos Molnar
8665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
876054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
877054219874873b41f1c815552987c10465c34ba2bLajos Molnar
87828edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
87928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
880d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
882d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode),
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
8865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
88728edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
88828edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
88928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
89028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
89128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
89228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
8935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
8945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
89534e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
89634e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
89734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
89828edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
899d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mode != IOMX::kPortModePresetSecureBuffer) {
9008a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                if (getTrebleFlag()) {
9018a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    mAllocator[portIndex] = TAllocator::getService("ashmem");
9028a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    if (mAllocator[portIndex] == nullptr) {
9038a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        ALOGE("hidl allocator on port %d is null",
9048a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                (int)portIndex);
9058a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        return NO_MEMORY;
9068a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    }
9078a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                } else {
9088a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    size_t totalSize = def.nBufferCountActual *
9098a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            (alignedSize + alignedConvSize);
9108a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
9118a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                }
912d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            }
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            const sp<AMessage> &format =
915fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                    portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
916054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
9178a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                hidl_memory hidlMemToken;
9188a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                sp<TMemory> hidlMem;
919d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                sp<IMemory> mem;
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
921ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
922ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
92315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
92490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
9251b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                info.mGraphicBuffer = NULL;
9261b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                info.mNewGraphicBuffer = false;
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
928d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                if (mode == IOMX::kPortModePresetSecureBuffer) {
929a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
9301b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    sp<NativeHandle> native_handle;
931d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->allocateSecureBuffer(
932d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            portIndex, bufSize, &info.mBufferID,
933a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
934a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
9354811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                    info.mData = (native_handle == NULL)
9364811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            ? new SecureBuffer(format, ptr, bufSize)
9374811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            : new SecureBuffer(format, native_handle, bufSize);
9385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = info.mData;
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
9408a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    if (getTrebleFlag()) {
9418a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        bool success;
9428a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        auto transStatus = mAllocator[portIndex]->allocate(
9438a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                bufSize,
9448a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                [&success, &hidlMemToken](
9458a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                        bool s,
9468a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                        hidl_memory const& m) {
9478a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    success = s;
9488a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    hidlMemToken = m;
9498a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                });
9508a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
9518a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        if (!transStatus.isOk()) {
9528a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            ALOGE("hidl's AshmemAllocator failed at the "
9538a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    "transport: %s",
9548a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    transStatus.description().c_str());
9558a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            return NO_MEMORY;
9568a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        }
9578a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        if (!success) {
9588a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            return NO_MEMORY;
9598a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        }
9608a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        hidlMem = mapMemory(hidlMemToken);
9618a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
9628a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        err = mOMXNode->useBuffer(
9638a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                portIndex, hidlMemToken, &info.mBufferID);
9648a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    } else {
9658a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        mem = mDealer[portIndex]->allocate(bufSize);
9668a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        if (mem == NULL || mem->pointer() == NULL) {
9678a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            return NO_MEMORY;
9688a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        }
969ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
9708a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        err = mOMXNode->useBuffer(
9718a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                portIndex, mem, &info.mBufferID);
9728a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    }
9735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
974d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    if (mode == IOMX::kPortModeDynamicANWBuffer) {
9758a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
9768a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                getTrebleFlag() ?
9778a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                (void*)hidlMem->getPointer() : mem->pointer());
9788a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        metaData->nFenceFd = -1;
979054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
9805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
9818a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    if (getTrebleFlag()) {
9828a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        info.mCodecData = new SharedMemoryBuffer(
9838a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                format, hidlMem);
9848a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        info.mCodecRef = hidlMem;
9858a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    } else {
9868a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        info.mCodecData = new SharedMemoryBuffer(
9878a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                format, mem);
9888a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        info.mCodecRef = mem;
9898a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    }
990d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
9915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // if we require conversion, allocate conversion buffer for client use;
9925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // otherwise, reuse codec buffer
9935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (mConverter[portIndex] != NULL) {
9945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        CHECK_GT(conversionBufferSize, (size_t)0);
9958a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        if (getTrebleFlag()) {
9968a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            bool success;
9978a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            mAllocator[portIndex]->allocate(
9988a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    conversionBufferSize,
9998a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    [&success, &hidlMemToken](
10008a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                            bool s,
10018a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                            hidl_memory const& m) {
10028a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                        success = s;
10038a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                        hidlMemToken = m;
10048a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    });
10058a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            if (!success) {
10068a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                return NO_MEMORY;
10078a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            }
10088a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            hidlMem = mapMemory(hidlMemToken);
10098a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            info.mData = new SharedMemoryBuffer(format, hidlMem);
10108a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            info.mMemRef = hidlMem;
10118a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        } else {
10128a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            mem = mDealer[portIndex]->allocate(
10138a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    conversionBufferSize);
10148a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            if (mem == NULL|| mem->pointer() == NULL) {
10158a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                return NO_MEMORY;
10168a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            }
10178a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            info.mData = new SharedMemoryBuffer(format, mem);
10188a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            info.mMemRef = mem;
10195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        }
10205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else {
10215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = info.mCodecData;
10225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = info.mCodecRef;
10235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
10251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
10271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
10281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1035dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    std::vector<ACodecBufferChannel::BufferAndId> array(mBuffers[portIndex].size());
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1037dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        array[i] = {mBuffers[portIndex][i].mData, mBuffers[portIndex][i].mBufferID};
1038dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
1039dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (portIndex == kPortIndexInput) {
1040dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->setInputBufferArray(array);
1041dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    } else if (portIndex == kPortIndexOutput) {
1042dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->setOutputBufferArray(array);
1043dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    } else {
1044dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        TRESPASS();
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1050e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
1051098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
1052098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        bool reconnect) {
10531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
10541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
10551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
10561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1057d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
1058d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
10591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
10611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
10621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
1065d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
10661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
10671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
10681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
10691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
10701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
10721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
10741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
10751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1077f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
1078e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
1079b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
1080fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
1081fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
1082fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
10831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
1084607e65286b7c3dcd06b7175c9d81b82e6fcfcb9aWonsik Kim    return setNativeWindowSizeFormatAndUsage(
10851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
10861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
10871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
10881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
10891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
1090098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            usage,
1091098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            reconnect);
10921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
10931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
10951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
1096098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        OMX_U32 *minUndequeuedBuffers, bool preregister) {
1097098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar
10981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
10991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
11001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
11011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1102d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
1103d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
11041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
11051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
1106098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        err = setupNativeWindowSizeFormatAndUsage(
1107098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar                mNativeWindow.get(), &mNativeWindowUsageBits, preregister /* reconnect */);
11081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
11091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
1110e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
11111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
11121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
11131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1114ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
1115ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
1116ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
1117ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1118ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1119ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
1120d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1121d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1122ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1123ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
1124ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
1125ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
1126ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
1127ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1128ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1129054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
1130258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
1131258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1132054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
1133258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1134258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
113529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1136258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
1137258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
1138258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1139258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1140e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
1141e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
11421faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
11431faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1144e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1145e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
1146e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
1147e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1148e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
1149e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
1150e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
11511faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
11521faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1153e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
1154e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1155258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1156d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1157d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1158258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1159e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1160e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1161e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1162e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1163e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1164609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1165e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1166e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1167e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1168258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1169258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1170258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1171258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
117629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1183054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1184054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1186054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1187d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    // This method only handles the non-metadata mode (or simulating legacy
1188d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    // mode with metadata, which is transparent to ACodec).
1189d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    CHECK(!storingMetadataInDecodedBuffers());
11903fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1192054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1193098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
1194054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1195054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1196e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1197054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
11983fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    static_cast<Surface*>(mNativeWindow.get())
11993fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            ->getIGraphicBufferProducer()->allowAllocation(true);
12003298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1201609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1203054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1206054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
12078ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
120815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
120915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
121129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121504e331c5032609f7ed42c344780b9c1b4cfe4afbMathias Agopian        sp<GraphicBuffer> graphicBuffer(GraphicBuffer::from(buf));
121674006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
121774006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
121815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
121915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
122090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
122174006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
12221b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang        info.mNewGraphicBuffer = false;
12233fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
12243fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode
12253fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        //       OMX doesn't use the shared memory buffer, but some code still
12263fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        //       access info.mData. Create an ABuffer as a placeholder.
1227d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1228d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mCodecData = info.mData;
12293fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
123074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
123174006804065941841883c4b46ee785070164023fJamie Gennis
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
12333fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId);
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1235609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
123674006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
124174006804065941841883c4b46ee785070164023fJamie Gennis
1242609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1250d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK) {
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
12523fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        // that were dequeued. Also cancel all if we're in legacy metadata mode.
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
125474006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1256054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1257054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
12633175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
12643175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
12653175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
12663175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
12673175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
12683fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12713fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    static_cast<Surface*>(mNativeWindow.get())
12723fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            ->getIGraphicBufferProducer()->allowAllocation(false);
12733fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1277054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1278d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    CHECK(storingMetadataInDecodedBuffers());
12793fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1280054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1281054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1282098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers,
12833fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            false /* preregister */);
1284d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK)
1285054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1286e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1287054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1288e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1289e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1290e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1291e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1292e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1293e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
129415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
129590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1296e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
12971b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang        info.mNewGraphicBuffer = false;
1298e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1299e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1300d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1301349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang
1302349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang        // Initialize fence fd to -1 to avoid warning in freeBuffer().
1303349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang        ((VideoNativeMetadata *)info.mData->base())->nFenceFd = -1;
1304349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang
13055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
1306e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1307d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID);
1308e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1309e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1310d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        ALOGV("[%s] allocated meta buffer with ID %u",
1311d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                mComponentName.c_str(), info.mBufferID);
1312e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1313e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1314054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1315054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1316054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1317054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1318054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1319054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1320054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1321054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1322054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1323054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
13240806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1325054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
13260806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1327054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1328609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
13291b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer->handle);
1330054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1331054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
133215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
13333fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    return fillBuffer(info);
1334054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1335054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
133615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
133715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
133815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
133915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
134015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
134115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
134215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
134315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
134415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
134515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
13460806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
13470806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
13480806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
13490806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
13500806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
13510806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
13520806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
13530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
13540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
13550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
13560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13570806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13580806340688c937e7b78c2d89db3809274130df4eLajos Molnar
13590806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
13600806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
13610806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
13620806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
13630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
13640806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
13650806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
13660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
13670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
13680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
13690806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13700806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13710806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1375609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
137815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
138015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
138115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13833fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
13843fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
13850806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13883fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
139290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
139390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
139490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
139590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
139690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
139790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
139890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
139990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
140090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
140190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
140290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
140390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
140490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
140590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
140690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
140790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
140890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
140990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
141090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
141190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
141290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
141390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
141490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1415604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1416604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1417604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1418604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1419604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1420604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
142190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
142290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
142390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
142479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCallback->onOutputFramesRendered(done);
142590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
142690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1427f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
14288ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1429054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1430ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1431ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1432ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1433ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1434ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1435ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1436ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1437346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1438346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1439346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1440346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1441346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
144215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1443dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
144415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
144515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
144615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1447dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1448dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1450dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1451b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1452b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1453dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1454dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1455dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
145690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1457dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1458dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1459dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1460dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1461dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1462dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1463dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1464dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1465dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1466dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1467dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1468dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
146990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
14701b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                ALOGV("dequeued buffer #%u with age %u, graphicBuffer %p",
14711b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                        (unsigned)(info - &mBuffers[kPortIndexOutput][0]),
14721b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                        mDequeueCounter - info->mDequeuedAt,
14731b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                        info->mGraphicBuffer->handle);
14741b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang
1475dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
147615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
147790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1478dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1479dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1480dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1482dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1483dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1484dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1485dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1486dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1487d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (!stale && !storingMetadataInDecodedBuffers()) {
1488dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1489dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1490dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1491dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1492dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1493dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1495dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1496054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1497dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1498dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1499b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1500b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1501dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1502dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1503054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1504054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1505054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1506054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1507054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1508054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1509054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1510054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1511054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
15120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
15130806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
15140806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
15150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1516054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1517054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
15180806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
151904e331c5032609f7ed42c344780b9c1b4cfe4afbMathias Agopian    oldest->mGraphicBuffer = GraphicBuffer::from(buf);
15201b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    oldest->mNewGraphicBuffer = true;
15210806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
152215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
152390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
152490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1525d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1526d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p",
1527d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1528d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mDequeueCounter - oldest->mDequeuedAt,
15291b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang            oldest->mGraphicBuffer->handle);
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
15320806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1536dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (portIndex == kPortIndexInput) {
1537dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->setInputBufferArray({});
1538dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    } else {
1539dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->setOutputBufferArray({});
1540dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
1541dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
1542777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1543938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1544938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1545777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1546777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1547777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1548777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15518a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    if (getTrebleFlag()) {
15528a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        mAllocator[portIndex].clear();
15538a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    } else {
15548a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        mDealer[portIndex].clear();
15558a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    }
1556777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1559349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1560777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1561938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1562938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15662ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
15672ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
15682ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
15692ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1570777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1571777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1572777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1573777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1577777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
15820806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
158415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
1585d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL
1586fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
1587fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim        int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd;
158815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
158915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
159015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
159115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
159215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
159315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
15940806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
15950806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
15960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
15970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
15980806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
15990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16010806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1602d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
16030806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
16040806340688c937e7b78c2d89db3809274130df4eLajos Molnar
16050806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
16060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
16070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
16080806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
161115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
161215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
161315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
161415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1615604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1616604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1617604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1618604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
161990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1620d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    // remove buffer even if mOMXNode->freeBuffer fails
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1622777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1625f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
16260806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1638777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16423fd200feb657c157125e45e30c2a7262e3c0244dChong Zhangstatus_t ACodec::fillBuffer(BufferInfo *info) {
16433fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    status_t err;
16441b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // Even in dynamic ANW buffer mode, if the graphic buffer is not changing,
16451b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // send sPreset instead of the same graphic buffer, so that OMX server
16461b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // side doesn't update the meta. In theory it should make no difference,
16471b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // however when the same buffer is parcelled again, a new handle could be
16481b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // created on server side, and some decoder doesn't recognize the handle
16491b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // even if it's the same buffer.
16501b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    if (!storingMetadataInDecodedBuffers() || !info->mNewGraphicBuffer) {
16513fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->fillBuffer(
16523fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            info->mBufferID, OMXBuffer::sPreset, info->mFenceFd);
16533fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    } else {
16543fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->fillBuffer(
16553fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            info->mBufferID, info->mGraphicBuffer, info->mFenceFd);
16563fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    }
16573fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
16581b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    info->mNewGraphicBuffer = false;
16593fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    info->mFenceFd = -1;
16603fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    if (err == OK) {
16613fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
16623fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    }
16633fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    return err;
16643fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang}
16653fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
16681ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime);
16695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
16705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
16715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
1672d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = SetComponentRole(mOMXNode, role);
16735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
16745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
16755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
16765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
16775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
16785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
16795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1687b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1688b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1689b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1690e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1693d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
1694d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
16958db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
17032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
17042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
17052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
170996bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    // propagate bitrate to the output so that the muxer has it
171096bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    if (encoder && msg->findInt32("bitrate", &bitRate)) {
171196bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
171296bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
171396bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("bitrate", bitRate);
171496bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("max-bitrate", bitRate);
171596bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    }
171696bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar
1717d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1718d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
17193e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
17203e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && storeMeta != kMetadataBufferTypeInvalid) {
1721d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        IOMX::PortMode mode;
1722d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
1723d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mode = IOMX::kPortModeDynamicNativeHandle;
1724d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
1725d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                storeMeta == kMetadataBufferTypeGrallocSource) {
1726d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mode = IOMX::kPortModeDynamicANWBuffer;
1727d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else {
1728d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            return BAD_VALUE;
1729d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        }
1730d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = setPortMode(kPortIndexInput, mode);
1731d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1732054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
1733054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1734c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1735c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1736d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
1737d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1738c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1739c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1740c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1741c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1742054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1744308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
17453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
17463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
17473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
17483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
1749d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getExtensionIndex(
1750d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
17513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
17533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
17543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
17553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
17563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1757d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(index, &params, sizeof(params));
17583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
17613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
17623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
17633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
17653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
17673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1768308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1769308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1770308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1771308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
17728db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1773308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1774308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
17753e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
1776308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1777d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (mFlags & kFlagIsSecure) {
1778d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            enable = OMX_TRUE;
1779d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        }
1780308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1781d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = setPortMode(kPortIndexOutput, enable ?
1782d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer);
1783308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1784d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            return err;
1785308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1786a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1787a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1788a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1789a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1790a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1791a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
179294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
17933604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        // only allow 32-bit value, since we pass it as U32 to OMX.
179494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
17952c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
17963604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < 0) {
17973604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang            ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs);
17983604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang            mMaxPtsGapUs = -1ll;
17992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
18002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
180137b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
180237b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
180337b2b389139ed638831e49708c947863eef631efRonghua Wu        }
180437b2b389139ed638831e49708c947863eef631efRonghua Wu
180522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        if (!msg->findDouble("time-lapse-fps", &mCaptureFps)) {
180622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mCaptureFps = -1.0;
180794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
180872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
180972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
181072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
181172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
181272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
181372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1814308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1815308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
18163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
18180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
18193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1820b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1821e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1822e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
18231713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
18241713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
18251713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
18261713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
18271713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
18281713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
18291713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
18301713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
18311713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
18321713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1833a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1834a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        if (mFlags & kFlagIsSecure) {
1835a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            // use native_handles for secure input buffers
1836d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer);
1837d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
1838d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (err != OK) {
1839d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                ALOGI("falling back to non-native_handles");
1840d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
1841d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                err = OK; // ignore error for now
1842d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            }
1843a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
18453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
18461de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
18471de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
18485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18496597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
18506597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
18516597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
18526597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
18536597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
18546597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
18556597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
1856d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t temp = mOMXNode->setConfig(
1857d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
18586597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
18596597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
18606597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
18616597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
18626597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
18636597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
18646597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
18656597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
18666597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
18675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
18685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
18695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
18705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1871ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
18725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
187397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
187497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
18755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
18765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
18785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
187997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
18805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
18815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1882fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1883fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1884d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1885d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1886d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1887d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1888d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mOMXNode->prepareForAdaptivePlayback(
1889d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1890d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1891d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1892d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
18933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
18943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1895d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1896d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1897d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1898d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1899d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1900d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
19015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1902ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1903ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1904ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
19053fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
19063fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
19073fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
19083fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
19093fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
19103fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
19113fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
19123fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
19133fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
1914d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer);
19155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
19165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
19175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
19185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
19195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
19215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
19225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
19235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
19245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
19255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
19275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
19285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
19295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
19305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
19315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
19325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
19335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
19345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
19355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
19365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
19375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
19395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
19405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
19415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
19425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
19435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
19445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1945d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->prepareForAdaptivePlayback(
1946d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
19475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
19485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
19495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
19505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
19525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
19535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
19545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
19555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1956e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1957cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang                // allow failure
1958cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang                err = OK;
19595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
1960d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                ALOGV("[%s] setPortMode on output to %s succeeded",
1961d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                        mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer));
1962054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
19635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1964fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
19650167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
19665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
19675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
19685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
19695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
19705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
19710167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1972e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1973e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1974e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1975e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1976e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1977e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1978e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1979054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
19815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
19825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
19835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
19845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
1985308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
19863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
19873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
19883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
19893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
19903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
1991cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            (void)setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
1992cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang        } else if (haveNativeWindow && !storingMetadataInDecodedBuffers()) {
1993cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer);
1994cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            if (err != OK) {
1995cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang                return err;
1996cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            }
19973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
2000b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2002b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
20063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
20073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
20101de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
20113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
2012cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            // fallback for devices that do not handle flex-YUV for native buffers
20133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
20143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
20153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
2016777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
2017777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
2018777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
2019777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
20203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
20213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
2022777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
2023777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
2024777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
2025777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
20263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
20273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
20281ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                if (!IsFlexibleColorFormat(
2029d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
20303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
20313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
20323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
20333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
20343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
2035e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
20363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
20373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
2038d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    // TODO: implement adaptive-playback support for bytebuffer mode.
2039d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    // This is done by SW codecs, but most HW codecs don't support it.
2040d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
2041d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    inputFormat->setInt32("adaptive-playback", false);
20423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
20433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
20443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
20453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
2046b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
2047b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
20503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
20513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
20543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
20553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
205642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
205742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
205842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
205942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
206042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
206142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
206242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
206342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
206442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
206542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
206642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
206742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
206842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
2069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2075aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
2076b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
20778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
20782965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
20798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
2080ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
2081ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
2082ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
2083aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
2084aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
2085aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
2086b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2087b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
2088b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
2089ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
20918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
20928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20932965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
20942965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
20952965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
20962965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
20978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
20988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
21008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
21028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
21048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
21068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
21088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21098045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
21108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21118045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
21128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
21148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21158045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
21168045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2118ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
21194471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
21202965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
21212965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2123729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2125729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2127729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2128729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2129729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2130729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2131729de186450f78c099637e1fce743fe531862c52Andreas Huber
2132729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
213617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
213717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
213817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
213917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
214017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2143ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
21442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
21452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
21462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
21472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
21482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
21492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
21502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2151516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2152cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2153cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2154516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2155cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
21562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2157516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2158516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2159516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
21612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2162516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2163516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2164516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
21662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
21672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2168516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2169516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
21702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2171ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2172ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2173ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2174ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2175ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2176ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2177ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
21785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2179ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
218097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
218197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
218297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
218397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
218497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
218597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
218697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
218797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
218897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
21898a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
21908a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
21918a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
21928a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
21938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
21948a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
21958a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
21968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
21978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2199729de186450f78c099637e1fce743fe531862c52Andreas Huber
22004471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
22014471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
22024471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
22034471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
22048b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
22058b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
22068b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
22079806555d3930be43e11106281dee354820ac1c88Andreas Huber
22088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
22098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
22108b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
22118b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
22129806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
22139806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
22149806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
22159806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
22169806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
22179806555d3930be43e11106281dee354820ac1c88Andreas Huber
2218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
222101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = OK; // ignore error
2222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
222401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = OK; // ignore error
2225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22278b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
22288b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
22298b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
223001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = OK; // ignore error
22318b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22328b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2233ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2234ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2235ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2236ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2237ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2238ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2239ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2240ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
224101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = OK; // ignore errors
224201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
224301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
224401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (err == OK) {
224501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = setVendorParameters(msg);
224601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (err != OK) {
224701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return err;
224801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
2249ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2250ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2251697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
22524e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2253b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
22544e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2255777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2256777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2257777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2258777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2259777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2260777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2261777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2262777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
22635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // create data converters if needed
22655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!video && err == OK) {
22665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
22675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (encoder) {
22685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
22705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexInput] != NULL) {
22715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
22725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        } else {
22745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
22755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
22765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexOutput] != NULL) {
22775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
22785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
22795b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
22805b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
22815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuangstatus_t ACodec::setLatency(uint32_t latency) {
228689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    OMX_PARAM_U32TYPE config;
228789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    InitOMXParams(&config);
228889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    config.nPortIndex = kPortIndexInput;
228989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    config.nU32 = (OMX_U32)latency;
229089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    status_t err = mOMXNode->setConfig(
229189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            (OMX_INDEXTYPE)OMX_IndexConfigLatency,
229289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            &config, sizeof(config));
229389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    return err;
229489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang}
229589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
229689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuangstatus_t ACodec::getLatency(uint32_t *latency) {
229789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    OMX_PARAM_U32TYPE config;
229889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    InitOMXParams(&config);
229989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    config.nPortIndex = kPortIndexInput;
230089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    status_t err = mOMXNode->getConfig(
230189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            (OMX_INDEXTYPE)OMX_IndexConfigLatency,
230289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            &config, sizeof(config));
230389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    if (err == OK) {
230489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        *latency = config.nU32;
230589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    }
230689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    return err;
230789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang}
230889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
23098b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
23108b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
23118b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
23128b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
23138b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
23148b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
23158b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
2316d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t temp = mOMXNode->setConfig(
2317d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigPriority,
23188b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
23198b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
23208b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
23218b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
23228b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
23238b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
23248b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2325ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2326ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2327ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2328ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2329ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2330ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2331ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2332ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2333ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2334ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2335ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2336ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2337ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2338ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2339ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2340ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2341ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2342ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2343ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2344d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2345d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2346ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2347ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2348ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2349ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2350ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2351ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2352ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2353870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2354870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2355870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2356870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2357d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getConfig(
2358d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2359870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2360870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2361870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2362870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2363870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2364870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2365870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2366870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2367870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2368870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2369d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2370d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2371870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2372870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2373870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2374870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2375870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2376870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2377870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2378870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2379870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2380870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2381870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2382d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2383d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2384870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2385870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2386870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2387870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2388870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2389870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2390870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2391870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2392870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2393870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2394870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2395870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2396870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2397870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2398870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2399870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2400870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2401d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2402d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2403870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2404870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2405870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2406870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2407870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2408870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2409870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2410870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2411870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2412870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2413870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2414870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2415870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2416870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2417870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2418870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2419870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2420870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2421870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2422870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2423870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2424870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2425870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2426870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2427870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2428870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2429d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2430d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
2431870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2432870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2433870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2434870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2435870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2436870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2437870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2438870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2439870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2440d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2441d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh,
2442d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &refreshParams, sizeof(refreshParams));
2443870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2444870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2445870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2446870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2447870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2448870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2449870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
24500f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnarstatus_t ACodec::configureTemporalLayers(
24510f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) {
24520f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!mIsVideo || !mIsEncoder) {
24530f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return INVALID_OPERATION;
24540f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24550f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24560f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString tsSchema;
24570f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!msg->findString("ts-schema", &tsSchema)) {
24580f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return OK;
24590f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24600f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24610f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numLayers = 0;
24620f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numBLayers = 0;
24630f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    int tags;
24640f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    char dummy;
24650f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
24660f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
24670f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
24680f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0) {
24690f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
24700f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
24710f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                    &numLayers, &dummy, &numBLayers, &dummy))
24720f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && (tags == 1 || (tags == 3 && dummy == '+'))
24730f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
24740f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        numLayers += numBLayers;
24750f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
24760f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
24770f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
24780f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
24790f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24800f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24810f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
24820f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    InitOMXParams(&layerParams);
24830f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    layerParams.nPortIndex = kPortIndexOutput;
24840f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2485d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2486d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2487d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &layerParams, sizeof(layerParams));
24880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
24900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
24910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (!(layerParams.eSupportedPatterns & pattern)) {
24920f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
24930f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24940f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24950f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numLayers = min(numLayers, layerParams.nLayerCountMax);
24960f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numBLayers = min(numBLayers, layerParams.nBLayerCountMax);
24970f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24980f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!inConfigure) {
24990f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
25000f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        InitOMXParams(&layerConfig);
25010f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPortIndex = kPortIndexOutput;
25020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.ePattern = pattern;
25030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPLayerCountActual = numLayers - numBLayers;
25040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nBLayerCountActual = numBLayers;
25050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
25060f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2507d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(
2508d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
25090f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerConfig, sizeof(layerConfig));
25100f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
25110f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.ePattern = pattern;
25120f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nPLayerCountActual = numLayers - numBLayers;
25130f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nBLayerCountActual = numBLayers;
25140f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.bBitrateRatiosSpecified = OMX_FALSE;
25150f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2516d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2517d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
25180f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerParams, sizeof(layerParams));
25190f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25200f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25210f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString configSchema;
25220f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) {
25230f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers);
25240f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
25250f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("webrtc.vp8.%u", numLayers);
25260f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
25290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGW("Failed to set temporal layers to %s (requested %s)",
25300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                configSchema.c_str(), tsSchema.c_str());
25310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
25320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2534d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2535d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
25360f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            &layerParams, sizeof(layerParams));
25370f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25380f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err == OK) {
25390f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)",
25400f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                tsSchema.c_str(), configSchema.c_str(),
25410f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                asString(layerParams.ePattern), layerParams.ePattern,
25420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                layerParams.nPLayerCountActual, layerParams.nBLayerCountActual);
25430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        if (outputFormat.get() == mOutputFormat.get()) {
25450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            mOutputFormat = mOutputFormat->dup(); // trigger an output format change event
25460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        }
25470f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        // assume we got what we configured
25480f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        outputFormat->setString("ts-schema", configSchema);
25490f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25500f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    return err;
25510f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar}
25520f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2558d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2559d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2571d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2572d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2578d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2579d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2585777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2586777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2587777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2588777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
25996e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
2601d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2602d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPortFormat, &format, sizeof(format));
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26116e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
26126e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
26136e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
26146e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
26156e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
26166e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
26176e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2620d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2621d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPortFormat, &format, sizeof(format));
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2625aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
26268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
26272965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
26282965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2629ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2630ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2631ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2632ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2653d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2654d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2663d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2664d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2674d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2675d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2693aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2695b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2696b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2697b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2698b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2699b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2700b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2701b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2702b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2703b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2704b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2705b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2706b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2707b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2708b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2709b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2710b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2711b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2712b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2713b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2714b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2715b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2716b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2717b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2718b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2719b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2720b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2722d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2723d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2736d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2737d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2745ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2746ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2747ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2748ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2749ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2752dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
27538045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
27548045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
27558045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
27568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
27578045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
27588045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
27592965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
27608045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2761d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t res = mOMXNode->setParameter(
2762d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
27638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
27648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
2765d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mOMXNode->setParameter(
2766d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
27678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
27688045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
27698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
27708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
2771b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    mSampleRate = sampleRate;
27728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
277597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
277697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
277797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
277897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
277997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
278097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
278197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
278297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
278397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
278497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
278597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
278697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
278797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
278897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
278997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
279097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
279197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
279297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2793d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2794d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
279597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
279697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
279797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
279897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
279997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
280097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
280197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
280297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2803d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2804d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
280597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
280697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
28078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
28088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
28098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
28108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
28118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
28138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
28148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
28158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
28178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
28188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
28198a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
28208a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28218a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
28228a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
28238a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
28248a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2825d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2826d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
28278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
28298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
28308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
28318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
28338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
28348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2835d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2836d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
28378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
28388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
28445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
28485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
28495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
28525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
28535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
28545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
28555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
28565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
28575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
28585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
28615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
28625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
28635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
28645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
28655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
28665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
28695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
28705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
28715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
28725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
28735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
28745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
28755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
28785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2885729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2886729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
28875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2888729de186450f78c099637e1fce743fe531862c52Andreas Huber
2889d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2890d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2891729de186450f78c099637e1fce743fe531862c52Andreas Huber
2892729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2893729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2894729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2895729de186450f78c099637e1fce743fe531862c52Andreas Huber
2896729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2899d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2900d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2901729de186450f78c099637e1fce743fe531862c52Andreas Huber
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2905729de186450f78c099637e1fce743fe531862c52Andreas Huber
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2910729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2911729de186450f78c099637e1fce743fe531862c52Andreas Huber
291217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2913777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2914777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2915777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2917729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
291817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2919729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2920729de186450f78c099637e1fce743fe531862c52Andreas Huber
29212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
29222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
29232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
29242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
29252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
29262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
29272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
29282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
29292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
2930d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
29312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
29322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
29332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
29342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
29352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
2936d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
29372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
29382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
29392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
29402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
29412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
29422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
29432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
29442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
29452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
29462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
29472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
29482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2949729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
29505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
2951729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2952729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2953729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2954729de186450f78c099637e1fce743fe531862c52Andreas Huber
2955d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2956d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2957729de186450f78c099637e1fce743fe531862c52Andreas Huber
2958729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2959729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2960729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2961729de186450f78c099637e1fce743fe531862c52Andreas Huber
2962729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2963729de186450f78c099637e1fce743fe531862c52Andreas Huber
2964d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2965d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2966729de186450f78c099637e1fce743fe531862c52Andreas Huber
2967729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2968729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2969729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2970729de186450f78c099637e1fce743fe531862c52Andreas Huber
2971729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2972729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2973729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2974729de186450f78c099637e1fce743fe531862c52Andreas Huber
2975d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2976d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2977729de186450f78c099637e1fce743fe531862c52Andreas Huber
2978729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2979729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2980729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2981729de186450f78c099637e1fce743fe531862c52Andreas Huber
2982729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
29835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    switch (encoding) {
29845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm8bit:
29855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataUnsigned;
29865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 8;
29875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcmFloat:
29895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataFloat;
29905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 32;
29915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm16bit:
29935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataSigned;
29945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 16;
29955b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
29965b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        default:
29975b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            return BAD_VALUE;
29985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
2999729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
3000729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
3001729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
3002729de186450f78c099637e1fce743fe531862c52Andreas Huber
3003c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
3004c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
3005729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
3006729de186450f78c099637e1fce743fe531862c52Andreas Huber
3007d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3008d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
30095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // if we could not set up raw format to non-16-bit, try with 16-bit
30105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // NOTE: we will also verify this via readback, in case codec ignores these fields
30115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (err != OK && encoding != kAudioEncodingPcm16bit) {
30125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.eNumData = OMX_NumericalDataSigned;
30135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.nBitPerSample = 16;
3014d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
3015d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
30165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
30175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return err;
3018729de186450f78c099637e1fce743fe531862c52Andreas Huber}
3019729de186450f78c099637e1fce743fe531862c52Andreas Huber
30205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
302197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
30225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
30235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
3024d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->configureVideoTunnelMode(
3025d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
30265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
30275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
30285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
30295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
30305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
30315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
30325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
30335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
30345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
30355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
30365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
30375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
30385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
30395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
30405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
30440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
30450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30526e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
3054d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3055d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat,
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3062229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
3063229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
30640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
30651ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
3066d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
30670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
3068229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
3069229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
3070229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
3071229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3072229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30976e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
30986e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
30996e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
31006e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
31016e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
31026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3109d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
3110d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
31160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
31170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
31180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
31190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
31200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
31210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
31220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
31230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
31240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
31250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
31260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
31270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
31280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
31290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
31300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31340d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
31350d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
31360d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
31390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
3140d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3141d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat, &format, sizeof(format));
31420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
31430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
31440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
31450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
31460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
31470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
31480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
31490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
31500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
31510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
31520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
31530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
31540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
31550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
31560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
31570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
31580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
31590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
31600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
31610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
31620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
31630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
31640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
31650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
31660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
31671ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
3168d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
31690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
31700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
31710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
31720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
31730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
3174d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
3175d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3178e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
3179e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
3180e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3181e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
3182e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
31832472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3184e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3185e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3186e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
318794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
318894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3189a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3190e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
3191e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
31935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3194e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3195e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3196e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3197e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3198e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3199e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3200e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3203e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3204e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3205e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3206e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3207e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3208e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3209e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3210e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3211e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3212e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3213e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3214e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3215e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3216e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3217e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3218e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3219e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3220e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3221e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3224a6bfb5060824f01041f956c733fec141504c280bHangyu Kuangstatus_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) {
3225a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
3226a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    InitOMXParams(&def);
3227a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nPortIndex = portIndex;
3228a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    status_t err;
3229a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
3230a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3231d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3232d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3233a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3234a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        return err;
3235a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3236a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nBufferCountActual = bufferNum;
3237d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3238d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3239a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3240a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        // Component could reject this request.
3241a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
3242a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3243a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3244a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    return OK;
3245a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang}
3246a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
32475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
32488338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3249b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
325089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
325189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
325289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
325389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
325489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
325589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
32565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
32575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
32585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3263f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    if (compressionFormat == OMX_VIDEO_CodingVP9) {
3264f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3265f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        InitOMXParams(&params);
3266f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nPortIndex = kPortIndexInput;
3267f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        // Check if VP9 decoder advertises supported profiles.
3268f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nProfileIndex = 0;
3269d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3270f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                OMX_IndexParamVideoProfileLevelQuerySupported,
3271d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
3272f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        mIsLegacyVP9Decoder = err != OK;
3273f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    }
3274f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang
32755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
328389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
328489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
328589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
328689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
32870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
328889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
328989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
329089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
32910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
329289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
329389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
32940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
329589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3301a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component input buffer number to be |tmp|. If succeed,
3302a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set input port buffer number to be |tmp|. If fail,
3303a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3304a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-input-buffers", &tmp)) {
3305a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexInput, tmp);
3306a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3307a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3308a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3309a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
3310a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component output buffer number to be |tmp|. If succeed,
3311a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set output port buffer number to be |tmp|. If fail,
3312a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3313a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-output-buffers", &tmp)) {
3314a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexOutput, tmp);
3315a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3316a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3317a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3318a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
331978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
332078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
332178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
332278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
332378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
332478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
332578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
332678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
332778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
332978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3342b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3343b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
33458338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
33468338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3347db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3348db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3349db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return err;
3350db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3351db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
33525e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
3353db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
3354db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        err = OK;
3355db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3356b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3357b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3358b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3360d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3361d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3362b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3363b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3364b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3365b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
33678338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3368b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3369b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3371d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3377b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3378b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3379b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3380b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3381b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3382b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3385b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3386db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting color aspects failed even though codec advertises support",
3387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
33888338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
33898338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
33908338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3391b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3392b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
33948338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
33958338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
33978338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3398b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
34058338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34068338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
34088338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3411b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3412b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3414b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3415b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3416d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
34178338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3418b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3419b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3420b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3424b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3425b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3427b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3434b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
34358338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3436b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3437b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3439b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3440b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3441b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3442b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3443b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
34448338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3445b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3446b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3447b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3448b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3449b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3450b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3451b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3452b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3453b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3454b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3455b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3456b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3457b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3458b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3459b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3460b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3461b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3462b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3463b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
34648338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3465b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3466b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3467b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3468b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3469b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3470b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3471b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3472b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3473b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3474b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3475b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3476b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3477b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3478b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3479b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3480b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3481b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3482b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3483b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3484b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3485b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3486b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3487b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3488b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3489b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3490b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
34918338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3492b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
34938338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3494b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3495b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3496b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3497b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3498b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3501b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
35028338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
35038338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3504b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
35058338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
35068338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3507b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3508b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3509b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
35358338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
35368338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3545b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3546b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3549b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3550b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
35525e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::setHDRStaticInfoForVideoCodec(
35535e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
35545e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
35555e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
35565e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    DescribeHDRStaticInfoParams params;
35575e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    InitOMXParams(&params);
35585e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
35595e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
35605e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    HDRStaticInfo *info = &params.sInfo;
35615e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (getHDRStaticInfoFromFormat(configFormat, info)) {
35625e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
35635e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
35645e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
35655e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    (void)initDescribeHDRStaticInfoIndex();
35665e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
35675e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    // communicate HDR static Info to codec
35685e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    return setHDRStaticInfo(params);
35695e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang}
35705e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
3571b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3572b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3573b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
35748338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
35758338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3576b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
35778338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
35788338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3579b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3580b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3581b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3582b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3583b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
35848338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3585b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3586b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
35878338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3588b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3589b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3590b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3591b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3592b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3593b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3594b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3595b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3596b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3597b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
35988338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
35998338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3600b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3601b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3602b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3603b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3604b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3605b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
36068338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3607b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3608b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3609b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3610b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3613b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3614b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
36158338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3616b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3617b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3618b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3619b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36235e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
36245e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3625db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    DescribeHDRStaticInfoParams params;
3626db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    InitOMXParams(&params);
36275e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
3628db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3629db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = getHDRStaticInfo(params);
3630db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == OK) {
3631db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        // we only set decodec output HDRStaticInfo if codec supports them
3632db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, format);
3633db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3634db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3635db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3636db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3637db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::initDescribeHDRStaticInfoIndex() {
3638d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3639d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
3640db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3641db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
3642db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3643db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3644db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3645db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3646db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
3647db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3648db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3649d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3650db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3651db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3652db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    const HDRStaticInfo *info = &params.sInfo;
3653db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
3654db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
3655db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str(),
3656db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
3657db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
3658db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
3659db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
3660db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3661db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3662db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting HDRStaticInfo failed even though codec advertises support",
3663db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3664db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3665db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3666db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3667db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
3668db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3669db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3670d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3671db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3672db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3673db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3674db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] getting HDRStaticInfo failed even though codec advertises support",
3675db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3676db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3677db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3678db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
36798338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3680b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3681b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3709d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3710d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
37295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
37325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
37345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
37355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
37365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
37395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
374222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    float framerate;
374322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    if (!msg->findFloat("frame-rate", &framerate)) {
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
374822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mFps = (double)tmp;
374922dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    } else {
375022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mFps = (double)framerate;
37515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
375322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    video_def->xFramerate = (OMX_U32)(mFps * 65536);
37545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3755a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3756a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3757a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3758a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3759a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3761d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3762d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
37665778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
37675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
37865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
37915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3792d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3793d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
37945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
38005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3806d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3807d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
38115778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
38125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3816870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3817870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3818870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3819870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3820870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3821870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3822870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3823870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3824870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3825870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3826870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
382789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    configureEncoderLatency(msg);
382889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
38295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
38305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
38405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
38415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3842c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3843c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3844c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3845c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
384689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
384789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
38489bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            err = setupVPXEncoderParameters(msg, outputFormat);
384989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
385089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
38515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
38525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
38535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38550f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
38560f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
38570f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
38580f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38598338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
38608338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3861b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3862b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
38638338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
38648338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
38658338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
38668338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
38675e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err != OK) {
38685e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        return err;
38695e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
38705e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
38715e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
38725e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
38735e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
38745e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        err = OK;
38755e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
38765e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
38770f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
38780f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
38790f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
38800f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38810f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    switch (compressionFormat) {
38820f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingAVC:
38830f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingHEVC:
38840f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat);
38850f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            if (err != OK) {
38860f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                err = OK; // ignore failure
38870f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            }
38880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP8:
38910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP9:
38920f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // TODO: do we need to support android.generic layering? webrtc layering is
38930f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // already set up in setupVPXEncoderParameters.
38940f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38950f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
38960f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        default:
38970f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
38980f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
38990f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
3900d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3901d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3902d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
39035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
39080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
39090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
39100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
39110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
39130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
39150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
39160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
39170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
39180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
39190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
39200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
39210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
39220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
39240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
39250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
39260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
39270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
39280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
39290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
39300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
39320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
39330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
39340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
39350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
39360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
39370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
3938d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
3939d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
39400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
39410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
39420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
3943f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnarstatic OMX_U32 setPFramesSpacing(
394463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar        float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) {
3945f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // BFramesSpacing is the number of B frames between I/P frames
3946f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // PFramesSpacing (the value to be returned) is the number of P frames between I frames
3947f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3948f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1
3949f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                                     ^^^                            ^^^        ^^^
3950f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                              number of B frames                number of P    I frame
3951f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3952f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                  = (PFramesSpacing + 1) * (BFramesSpacing + 1)
3953f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3954f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // E.g.
3955f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //      I   P   I  : I-interval: 8, nPFrames 1, nBFrames 3
3956f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //       BBB BBB
3957f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
3958f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    if (iFramesInterval < 0) { // just 1 key frame
3959f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1
3960f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    } else if (iFramesInterval == 0) { // just key frames
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3963f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
3964f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // round down as key-frame-interval is an upper limit
3965f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval);
3966f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1);
3967f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    return ret > 0 ? ret - 1 : 0;
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
397096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
397196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
397296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
397396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
397496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
397596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
397696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
397796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
397896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
39795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
398063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
398163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
398363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
39855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
398796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
398896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
39895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
39915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
39925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
39935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
39965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
39995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
40005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
40015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4002d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4003d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
40045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
40105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
40115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
40125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
40145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
40155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4016f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nBFrames = 0;
4017f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames);
40185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
40195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
40205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
40225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
40235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
40245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
40255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
40265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
40275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
40295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
40305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
40315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
40325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
40335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
40365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
40385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
40395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
40425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4045d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4046d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
40475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
405296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
40535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
40595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
406263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
406363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
40645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
406563a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
40665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
40675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
406996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
407096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
40715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
40725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
40735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
40745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
40755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
40765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
40785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
40815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
40825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
40835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4084d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4085d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
40865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
40925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
40935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4094f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nBFrames = 0;
4095f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames);
40965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
40975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
40985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
41015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
41025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
41035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
41045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
41055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
41085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
41105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
41115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
41145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
41155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
41185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
41195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
41205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
41215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4122d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4123d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
41245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
412996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
41305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
41365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4138a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
4139a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
4140a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
4141a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
4142a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
4143a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
4144a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
4145a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
4146a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
4147a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
4148a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
4149a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
4150a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4151a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4152a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
4153a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
4154a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
4155a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
4156a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
4157a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
4158a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4159a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
4160a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
4161a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
4162a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
4163a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
4164a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
4165a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
4166a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
4167a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
4168a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
4169a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
4170a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
4171a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
4172a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
4173a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
4174a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
4175a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
4176a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
4177a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
4178a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
4179a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4180a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
4181a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
4182a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
4183a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
4184a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
4185a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
4186a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4187a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
4188a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
4189a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
41905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
419163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
419263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
419463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
41955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
41965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
419896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
419996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
42005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
42015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
42025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
42035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
42055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
42075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
42100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
42110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
42120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
42130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
42140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
42150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
42160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
42170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
42180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
42190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
42205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
42215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
42225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
42235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4224d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4225d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
42265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
42295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
42325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
42335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
42355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
42365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
42375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
42385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
42395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
42425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
42445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
42455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
42485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
4249e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else {
42508eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
42514c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#if 0   /* DON'T YET DEFAULT TO HIGHEST PROFILE */
42524c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar        // Use largest supported profile for AVC recording if profile is not specified.
4253826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        for (OMX_VIDEO_AVCPROFILETYPE profile : {
4254826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
4255826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            if (verifySupportForProfileAndLevel(profile, 0) == OK) {
4256826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                h264type.eProfile = profile;
4257826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                break;
4258826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            }
4259826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        }
42604c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#endif
42618eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    }
42628eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang
4263e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
4264e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            asString(h264type.eProfile), asString(h264type.eLevel));
4265e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang
42665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
42675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
42685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
42695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
42705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
4271f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
42725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
42735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
42745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
42765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
42775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
42785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
42795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
42805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
42815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
42825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
4283e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
4284e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
4285e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nSliceHeaderSpacing = 0;
4286e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
4287e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefFrames = 2;
428889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1);
4289f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4290e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nAllowedPictureTypes =
4291e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
4292e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
4293e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
4294e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
4295e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
4296e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bconstIpred = OMX_TRUE;
4297e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
4298e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
4299e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nCabacInitIdc = 1;
43005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
43035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
43045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
43075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
43085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
43095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
43105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
43115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
43125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
43135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4314d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4315d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
43165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
43185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
43195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4321e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering
4322e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering
4323e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // is preferred.
4324e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    AString tsSchema;
4325e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    int32_t preferBFrames = (int32_t)false;
4326e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    if (msg->findString("ts-schema", &tsSchema)
4327e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) {
4328e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
4329e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        InitOMXParams(&layering);
4330e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        layering.nPortIndex = kPortIndexOutput;
4331d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
4332d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
4333e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                        &layering, sizeof(layering)) == OK
4334e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.eSupportedPatterns
4335e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.nBLayerCountMax == 0) {
4336e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nBFrames = 0;
4337e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4338e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
4339e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            ALOGI("disabling B-frames");
4340d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(
4341d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4342e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
4343e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            if (err != OK) {
4344e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                return err;
4345e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            }
4346e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        }
4347e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    }
4348e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
434996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
43505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
43515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4352c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
435363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
435463a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
4355c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
435663a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4357c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
4358c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4359c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4360c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
4361c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4362c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
4363c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
4364c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
4365c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
4366c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4367c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4368c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
4369c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4370c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4371c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4372c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4373c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4374c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4375c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4376d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4377d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4378c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4379c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4380c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4381c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4382c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4383c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4384c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4385c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4386c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4387c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4388c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4389c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
4390c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4391c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4392c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4393c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4394c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4395c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4396c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
43979aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
4398f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
4399c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4400d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4401d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4402c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4403c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4404c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4405c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4406c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
4407c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4408c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
44099bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnarstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
441089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
441163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval = 0;
44124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
44134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
44144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
44154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
44164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
44174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
44184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
44194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
44204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
44214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
442289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
442389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
442489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
442563a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    msg->findAsFloat("i-frame-interval", &iFrameInterval);
442689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
442789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
442889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
44294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
44304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
44314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
44324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
44334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
44344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
44364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
44374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
44384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
44399bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType =
44409bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
44419bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar
44424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
4443f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numLayers = 0;
4444f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numBLayers = 0;
4445f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        int tags;
4446f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        char dummy;
4447f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
4448f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0) {
44494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
44509bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
4451f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers;
4452f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
4453f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                        &numLayers, &dummy, &numBLayers, &dummy))
4454f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && (tags == 1 || (tags == 3 && dummy == '+'))
4455f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
44564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4457f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            // VPX does not have a concept of B-frames, so just count all layers
44589bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4459f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers + numBLayers;
44604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
4461f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
44624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
4463f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS);
44644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
44654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
44664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
44674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
44684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
4469d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4470d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
44714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
44724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
44734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
44744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
4475f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
44764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
44784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
44794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
44804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
44814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
44824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
44834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
44844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
44864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
44874154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
44884154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
44894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
4490d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
4491d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
44924154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
44934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
44944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
44959bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
44969bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // advertise even single layer WebRTC layering, as it is defined
44979bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers));
44989bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsLayers > 0) {
44999bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid
45009bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers));
45014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
45024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
45034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
450489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
450589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
450689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
45075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
45085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
45095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
45105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
45115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
45125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45136e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
45146e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
4515d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
45165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
4517d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
45185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
45205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
45215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
45225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
45245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
45255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
45275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
45285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
45296e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
45306e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
45316e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
45326e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
45336e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
45346e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
45355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45366e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
45375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
45385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
453996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
454096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
45415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
45425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
45435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
45445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4545d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4546d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
45475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
45495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
45505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
455296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
45535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
45545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4555d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4556d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
45575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
45585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
455989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuangvoid ACodec::configureEncoderLatency(const sp<AMessage> &msg) {
456089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    if (!mIsEncoder || !mIsVideo) {
456189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        return;
456289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    }
456389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
456489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    int32_t latency = 0, bitrateMode;
456589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    if (msg->findInt32("latency", &latency) && latency > 0) {
456689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        status_t err = setLatency(latency);
456789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        if (err != OK) {
456889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            ALOGW("[%s] failed setLatency. Failure is fine since this key is optional",
456989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                    mComponentName.c_str());
457089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            err = OK;
457189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        } else {
457289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            mLatency = latency;
457389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        }
457489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    } else if ((!msg->findInt32("bitrate-mode", &bitrateMode) &&
457589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            bitrateMode == OMX_Video_ControlRateConstant)) {
457689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        // default the latency to be 1 if latency key is not specified or unsupported and bitrateMode
457789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        // is CBR.
457889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        mLatency = 1;
457989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    }
458089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang}
458189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
45825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
45835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
45845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
45855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
45865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4587d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4588d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
45895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
45905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
45925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
45935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
45945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
45955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
45965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
45975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
45985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
45995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
46005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4601d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4602d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
46035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
46045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
46055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
460878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
460978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4616d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4617d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4618777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4619777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4620777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4630777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4631777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4632777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4633777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
464178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
464278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
464378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4646d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4647d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4652d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4653d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4654d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4655d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4656d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4657d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4658d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4659d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4660d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4661d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4662d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4663d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4664d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4665d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
46667e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
46677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
46687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
46697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
46707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
46717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
46727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
46737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
46747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
46757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
46767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
46777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
46787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
46797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
46807e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
46817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
46827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
46837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
46847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4685e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
46867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4687c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4688054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4689054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4690c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
46917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
46927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
46937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4701609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4730e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4731777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
473231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
473331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4734e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
473531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4736d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
4737777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4738777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4739777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
474031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4741777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4742777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4743777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4744777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
474531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
474631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
474731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
474831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
474931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4750e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4751e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4752e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4753e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4754e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4755e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4756e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4757e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4758e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4759e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
47600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
476173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
47620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
47630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
47640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
47650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
47660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
47670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
47680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
47690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
4770d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (DescribeColorFormat(mOMXNode, describeParams)) {
47710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
47720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
47730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
47740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
47750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
47765a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
477773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
477873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
477973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
478073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
478173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
478273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
478373dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
47840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
478503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
478603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4787b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4788b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4789b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4790b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4791b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4792b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4793b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4794b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4795d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (mOMXNode->getConfig(
4796b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4797b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4798b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4799b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4800b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4801b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4802b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4803b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4804b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
480591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4806b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4807b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4808b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4809b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4810b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4811b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4812b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4813b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4814b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4815b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
481631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4817b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4818b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4819b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4820b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4821b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4822b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4823b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4824b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4825b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4826b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4827b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4828b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4829b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4830b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4831b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4832b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4833b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
48345e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
4835b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4836b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
48375e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        if (mConfigFormat->contains("hdr-static-info")) {
48385e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                            (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
48395e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        }
484089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                        uint32_t latency = 0;
484189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                        if (mIsEncoder && getLatency(&latency) == OK && latency > 0) {
484289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                            notify->setInt32("latency", latency);
484389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                        }
4844777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
48484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
48494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
48504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
48514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
48524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
48534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
48544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
4855d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    status_t err = mOMXNode->getParameter(
48564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
48574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
48584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
48594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
48604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
48619bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                        if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC
48629bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount > 0
48639bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount
48649bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
48659bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            // advertise as android.generic if we configured for android.generic
48669bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            AString origSchema;
48679bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            if (notify->findString("ts-schema", &origSchema)
48689bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                    && origSchema.startsWith("android.generic")) {
48699bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
48709bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "android.generic.%u", vp8type.nTemporalLayerCount));
48719bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            } else {
48729bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
48739bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount));
48744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
48754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
48764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
48774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
48784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
48794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4880e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4881e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4882777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4883777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4884777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4885777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4886777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4887777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4888777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4889e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4891e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4892e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4894e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4895e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4896870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4897870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4898870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4899870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4900870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4902e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
490331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4904e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4905e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
49065a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
49075a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
49085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
49095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
491031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
491131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
491231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
491331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
491431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
491531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
491631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
491797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4918e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4919e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4920e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4921e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4922e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4923e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4924d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4925d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioPcm, &params, sizeof(params));
4926777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4927777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4928777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
492914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4931777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4932777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
49335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4934777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4935777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
49365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
4937777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4938777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4939e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4940e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4941e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4942e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
49435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
49445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
49455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
49465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
49475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
49485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
49495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
49505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
49515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
49525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
49535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
49545b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
49555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
49565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
49575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
49585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
4959e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4960e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4961e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
49628b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4963e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
49648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
49659806555d3930be43e11106281dee354820ac1c88Andreas Huber
4966e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4967e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4968e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4969e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4971e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4972d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4973d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAac, &params, sizeof(params));
4974777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4975777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4976777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4977e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4978e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4979e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4980e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4981e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4982e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4984e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4985e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4986e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4987e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4988e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
49899806555d3930be43e11106281dee354820ac1c88Andreas Huber
4990d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4991d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAmr, &params, sizeof(params));
4992777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4993777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4994777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4995e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4996e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4997e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
49980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4999e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
5000e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
50010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
5002e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
5003e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
5004e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
5005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
5006e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5007e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
5008e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
5009e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
5010e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
5011e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
5012e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5013d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5014d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioFlac, &params, sizeof(params));
5015777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5016777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5017777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5018e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5019e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
5020e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
5021e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
5022e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
5023e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
5024e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5025e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
5026e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
5027e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
5028e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
5029e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
5030e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5031d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5032d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioMp3, &params, sizeof(params));
5033777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5034777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5035777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5037e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
5038e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
5039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
5040e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
5041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
5042e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5043e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
5044e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
5045e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
5046e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
5047e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
5048e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5049d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5050d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioVorbis, &params, sizeof(params));
5051777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5052777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5053777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5054e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5055e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
5056e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
5057e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
5058e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
5059e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
5060e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
506197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
506297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
506397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
506497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
5065e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
506697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
5067d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5068d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
5069777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5070777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5071777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5072777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
507397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
507497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
507597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
507697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
507797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
507897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
5079e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
50808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
50818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
50828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
50838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
50848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
50858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
5086d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5087d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
5088777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5089777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5090777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5091777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
50928a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
50938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
50948a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
50958a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
50968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
50978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
50988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
50998c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
51008c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
51018c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
51028c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
51038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
51048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
5105d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5106d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
5107777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5108777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5109777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5110777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
51118c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
51128c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
51138c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
51148c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
51158c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
51168c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
51178c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
511810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
511910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
512010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
512110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
512210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
512310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
5124d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5125d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
5126777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5127777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5128777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
512910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
513010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
513110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
513210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
513310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
513410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
513510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
513610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
513710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
513810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
513910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
514010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
514178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
514210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
514310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
514441d3f579d2c166984958263533284209b90c87d5Marco Nelissen
514541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
514641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
51470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
514841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
514941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
515041d3f579d2c166984958263533284209b90c87d5Marco Nelissen
5151d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5152d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                OMX_IndexParamAudioPcm, &params, sizeof(params));
5153777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5154777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5155777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
515641d3f579d2c166984958263533284209b90c87d5Marco Nelissen
515741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
515841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
51590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
516041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
516110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
516210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
5163e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
5164777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
5165777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
5166777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
5167e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
516831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
516931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
517031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
517131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
5172777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
5173777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
517431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
517531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
517601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    return getVendorParameters(portIndex, notify);
5177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
5178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5179b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
5180b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
5181b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
5182b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
5183b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5184b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
5185b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5186b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
5187b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5188b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5189b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
5190b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5191b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5192b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
5193b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5194b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5195b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5196b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5197b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
5198b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5199b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5200b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
5201b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5202b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5203b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
5204b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5205b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5206b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5207b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5208b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
5209b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
5210b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
5211b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5212b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
5213b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
5214b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
5215b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
5216b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
5217b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
52181734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5219697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // store new output format, at the same time mark that this is no longer the first frame
5220b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
5221e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5222b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5223777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5224777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
5225777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5226e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
52271734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    if (expectedFormat != NULL) {
52281734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
52291734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
52301734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        if (changes->countEntries() != 0 || to->countEntries() != 0) {
52311734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
52321734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mComponentName.c_str(),
52331734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    changes->debugString(4).c_str(), to->debugString(4).c_str());
52341734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        }
52351734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    }
52361734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar
52375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
52385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
52395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
52405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
52415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
52425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
52435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
52445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
52455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
52465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
52475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
52485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
5249b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
5250b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
5251b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5252b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5253b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5254b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
5255b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
5256b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5257b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5258b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5259b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        int32_t channelCount, sampleRate;
526084d7e874983ee0d66db328c454fa603374d4635fMarco Nelissen        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5261b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
5262b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        if (mSampleRate != 0 && sampleRate != 0) {
5263b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderDelay = mEncoderDelay * sampleRate / mSampleRate;
5264b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderPadding = mEncoderPadding * sampleRate / mSampleRate;
5265b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mSampleRate = sampleRate;
5266b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        }
5267e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
5268e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
5269e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
5270ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5271e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
5272e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
5273b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5274e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
5275e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5276b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5277b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
527831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
527931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
52805778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5281251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5282251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
5283251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
5284251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
5285251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
5286251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
5287251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
5288251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5289251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5290251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5291346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5292346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
529379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCallback->onError(internalError, ACTION_CODE_FATAL);
5294cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5295cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5296496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5297496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5298496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5299496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5300496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5301496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5302496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5303496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5304496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5305496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5306496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5307d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setConfig(
5308496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5309496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5310496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5311496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5312496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
53137e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim////////////////////////////////////////////////////////////////////////////////
53147e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
5315f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5320ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5321ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
533926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
534026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
534126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
534226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
534326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5344e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5345e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5346e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5347e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5348e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5349e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
535226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
53561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
53571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
53581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
53591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
53611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
53621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53632235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
53641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
53661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
53671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
53681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
53691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
53701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
53717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
53728f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
53737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
53747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5375251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
53767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
53777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
53787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
53797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
53807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5381ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5382ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5383251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5384ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
53856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            mCodec->mGraphicBufferSource.clear();
5386ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5387ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5388ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5389ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
539030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
539130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
539230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
539330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
5394d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->freeNode();
539530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
539630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
539779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onReleaseCompleted();
539830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
539930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
540030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
540826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
54095e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
54105e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5411d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode == NULL) {
54125e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
54135e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
541426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
54155e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
54165e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5417d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    int32_t generation;
5418d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(msg->findInt32("generation", (int32_t*)&generation));
5419d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (generation != mCodec->mNodeGeneration) {
5420d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        ALOGW("Unexpected message for component: %s, gen %u, cur %u",
5421d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
5422777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5423777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
542426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
542526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
542626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
542726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
542826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
542926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
543026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
543126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
543290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
543326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
543426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5435e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5436e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
543790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
543890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
543990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
544090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
544190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
544290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
544390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
544490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
544590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
544690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
544726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
544826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
544926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
545026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
545126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
545226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
545326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54630af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
54640af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
54650af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
54660af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
54670af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
54680af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
54690af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
54700af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
54710af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
54720af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
54730af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
548315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
548415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5485609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
548615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
548815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5494609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
549615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
550315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
550915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
551015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
551490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
551590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
551690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
551790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
551890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
551990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
552090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
552190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
552290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
552390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5525777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5526777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
553090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
553190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
553290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
553390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
553490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
553590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5536f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
55396cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang        ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
5540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5546ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5552ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5554251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5555251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5556251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5557251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5558251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5559251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5560251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5566ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5567349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5568349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
55690806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
55700806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
55710806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
55720806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
55730806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
557415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
557515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
557615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
55770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
55780806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
558215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
558315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
558415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
558515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
558615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
558715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
558896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
558996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
559096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
559196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
559296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
559396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5594d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5605777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5607777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5608777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5621ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim    info->mData->setFormat(mCodec->mInputFormat);
5622dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mCodec->mBufferChannel->fillThisBuffer(info->mBufferID);
562379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    info->mData.clear();
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5627f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5629609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
56307e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
5631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
56325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5633a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
563476d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    int32_t discarded = 0;
563576d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    if (msg->findInt32("discarded", &discarded) && discarded) {
5636dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        // these are unfilled buffers returned by client
5637dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        // buffers are returned on MediaCodec.flush
5638dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mode = KEEP_BUFFERS;
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
564076d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    sp<RefBase> obj;
564176d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    CHECK(msg->findObject("buffer", &obj));
564276d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    buffer = static_cast<MediaCodecBuffer *>(obj.get());
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
56455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
56465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
56475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
56485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
56495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
56510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
56520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
56530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
56540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
56550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
56560806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
56570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5660fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    info->mData = buffer;
5661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5666dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5667dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5668dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5669dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
56765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5677fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5678fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5679fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5680fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5681fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5682fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5688d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                int32_t isCSD = 0;
5689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5690f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    if (mCodec->mIsLegacyVP9Decoder) {
5691f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
5692f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                            mCodec->mComponentName.c_str(), bufferID);
5693f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        postFillThisBuffer(info);
5694f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        break;
5695f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    }
5696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
57005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
57015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
57025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5703fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                size_t size = buffer->size();
570449b2b4d30a0f74314630a5ea5f0e59697d90443eChong Zhang                size_t offset = buffer->offset();
5705fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                if (buffer->base() != info->mCodecData->base()) {
5706ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5707d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5708d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
5709fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                         buffer->base(), info->mCodecData->base());
5710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
5712d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (converter == NULL || isCSD) {
57135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
57145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
57155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
57165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
57175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
57180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
57190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5720fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                    size = info->mCodecData->size();
57213fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                } else {
572249b2b4d30a0f74314630a5ea5f0e59697d90443eChong Zhang                    info->mCodecData->setRange(offset, size);
5723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5725078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5726ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5727078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
57285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5729ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
57305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5731078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5732d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5733ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5734ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5735d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5736ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5737ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5738d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5739078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5740349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5741d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5742d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5744d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5745d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5748054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5752054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5753054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5757054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
576015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5761d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5762d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                status_t err2 = OK;
5763d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                switch (mCodec->mPortMode[kPortIndexInput]) {
5764d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetByteBuffer:
5765d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetANWBuffer:
5766d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetSecureBuffer:
57673fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    {
57683fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
57693fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
57703fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    }
5771d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5772d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5773d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModeDynamicNativeHandle:
5774d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
5775d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeHandleMetadata *vnhmd =
5776d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            (VideoNativeHandleMetadata*)info->mCodecData->base();
57773fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        sp<NativeHandle> handle = NativeHandle::create(
57783fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                                vnhmd->pHandle, false /* ownsHandle */);
57793fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
57803fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, handle, flags, timeUs, info->mFenceFd);
5781d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5782d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5783d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModeDynamicANWBuffer:
5784d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
5785d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
578604e331c5032609f7ed42c344780b9c1b4cfe4afbMathias Agopian                        sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer);
57873fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
57883fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, graphicBuffer, flags, timeUs, info->mFenceFd);
5789d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5790d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5791d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#endif
5792d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                default:
5793d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
5794d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                            asString(mCodec->mPortMode[kPortIndexInput]),
5795d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                            info->mCodecData->size(),
5796d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            sizeof(buffer_handle_t) * 8);
5797d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    err2 = ERROR_UNSUPPORTED;
5798d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5799d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
5800d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
580115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
58020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
58030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
58040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
58050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5807fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                // Hold the reference while component is using the buffer.
5808fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                info->mData = buffer;
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
58115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
58125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
58130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
58140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
58155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
58165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
58175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
58185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
58200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
58210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5822dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5823dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
58243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5825dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5826dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5828ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5829349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5830349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
583115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5832d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                status_t err2 = mCodec->mOMXNode->emptyBuffer(
58333fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd);
583415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
58350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
58360806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
58370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
58380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5842dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5846625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5847777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5848777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5849777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5850625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5851777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5852625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
588915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
589015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5891609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
58925778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5893349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
58950806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5896d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5897d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5898d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5899d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5900d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5901d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5902d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5903d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5904d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5905d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5906d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5907d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5908d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5909d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5910d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5911d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
59140806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
59150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
59160806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
59170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
59180806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
591915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
592015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
592115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
59220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
59230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5925054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
592890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
592990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
593090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
593190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
593290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
593390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
593490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
593590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
593690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
593715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
593815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
593915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
594015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
594115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
594215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
594315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5952a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5953a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5954609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
59555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5956349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
59573fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                err = mCodec->fillBuffer(info);
59580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
59590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
59610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
59625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
59635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
596431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5965ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim            sp<MediaCodecBuffer> buffer = info->mData;
5966577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5967b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5968697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                // pretend that output format has changed on the first frame (we used to do this)
5969697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
59701734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
5971697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                }
5972b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
59735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5974ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim            buffer->setFormat(mCodec->mOutputFormat);
5975b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5976d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mCodec->usingSecureBufferOnEncoderOutput()) {
5977054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
5978d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get());
5979d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                if (secureBuffer != NULL) {
59807c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
59813e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    // handle is only valid on 32-bit/mediaserver process
59827c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
59837c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
5984d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    handle = (native_handle_t *)secureBuffer->getDestinationPointer();
59857c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5986054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
59877e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setPointer("handle", handle);
59887e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeOffset", rangeOffset);
59897e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeLength", rangeLength);
5990fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            } else if (buffer->base() == info->mCodecData->base()) {
59917e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->setRange(rangeOffset, rangeLength);
59925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
59935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
59945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
59955b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
59967e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                        info->mCodecData, buffer);
59975b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
59985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
60005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
6001308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
6002496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
600321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
6004496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
6005496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
6006496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
60075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
600821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60108b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
60117e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                mCodec->mSkipCutBuffer->submit(buffer);
60128b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
60137e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            buffer->meta()->setInt64("timeUs", timeUs);
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6015fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            info->mData.clear();
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6017dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags);
60185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
60195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
60225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
60235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
602479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mCallback->onEos(mCodec->mInputEOSResult);
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6030777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
60310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
60320806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
60330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
60350806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6037777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6038777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6039777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6040777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
6048609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
60497e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<RefBase> obj;
605076d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    CHECK(msg->findObject("buffer", &obj));
605176d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
605276d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    int32_t discarded = 0;
605376d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    msg->findInt32("discarded", &discarded);
605476d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
60560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
60570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
60580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
60590806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
60600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
60610806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
60620806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
60630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6064fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    info->mData = buffer;
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
60676aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
606876d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim            && !discarded && buffer->size() != 0) {
60696fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6072dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        android_native_rect_t crop;
6073dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
6074dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            // NOTE: native window uses extended right-bottom coordinate
6075dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            ++crop.right;
6076dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            ++crop.bottom;
6077dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
6078dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                mCodec->mLastNativeWindowCrop = crop;
6079dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
6080dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
6081dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            }
6082dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        }
6083dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
6084dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        int32_t dataSpace;
6085dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        if (buffer->format()->findInt32("android._dataspace", &dataSpace)
6086dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                && dataSpace != mCodec->mLastNativeWindowDataSpace) {
6087dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            status_t err = native_window_set_buffers_data_space(
6088dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
6089dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mCodec->mLastNativeWindowDataSpace = dataSpace;
6090dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
6091dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        }
6092dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
609390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
609490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
60957e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
609690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
609790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
609890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
609990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
610090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6101fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
6102fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
6103c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
61047e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
6105c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
6106fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
6107fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
6108fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
6109fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
61105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
6111fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
61120806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
6113fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
611415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
61150806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
611615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
611715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
61180806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
6119cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
6120cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
6121264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
6122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6123cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
612415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
612515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
6126cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
612876d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim        if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) {
612915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
613015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
61316fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
61326fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
6148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6162c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
6163609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
6164c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
616515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
61663fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    status_t err = mCodec->fillBuffer(info);
61673fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    if (err != OK) {
61680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
61690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
6170c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
6171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6175777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
61770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
61780806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
61790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
61800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6183777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6184777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6185777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6186777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6192f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
6193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
6197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
6198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
62001d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        if (mCodec->mOMXNode != NULL) {
62018a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            if (mCodec->getTrebleFlag()) {
6202ac7d4125516299b8a3e6f2b25822a692bdd96311Pawin Vongmasa                auto tOmxNode = mCodec->mOMXNode->getHalInterface();
62038a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                tOmxNode->unlinkToDeath(mDeathNotifier);
62048a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            } else {
62058a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
62068a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                binder->unlinkToDeath(mDeathNotifier);
62078a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            }
62081d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        }
6209ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
6210ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
6211ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6212b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
6213ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
6214e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
6215ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
6216d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode.clear();
6217ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6218d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
6219d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
62205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
62215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6222ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
62385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
62395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
62405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
62415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
62425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
62435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
624954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
625054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
625179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            if (keepComponentAllocated) {
625279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mCallback->onStopCompleted();
625379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            } else {
625479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mCallback->onReleaseCompleted();
625579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            }
6256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6257c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
626279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onFlushCompleted();
6263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6264c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
626730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
626830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
626930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
627030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
627130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
627230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
627330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6281f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6285c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6286c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
62875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
62885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
62905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
62915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6292d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode == NULL);
62935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
62959c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    bool trebleFlag;
62969c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    if (client.connect(&trebleFlag) != OK) {
629748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
629848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
629948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
63009c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    mCodec->setTrebleFlag(trebleFlag);
6301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6305ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6306b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
63075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
63117791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
63125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6313b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6314b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6315b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6316afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
63175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
63185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
63195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
63205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
63215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
63225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
63235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6324b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
63255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
63265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6327b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6328e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
63295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
63301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
63311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6332d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
63331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6334201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
63351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
63361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6337b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6339da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6340078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6341078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
63421d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
6343078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
63461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
63477a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
63487a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
63491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
63501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6351d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode = NULL;
63521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
63531065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6354d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (omxNode == NULL) {
63555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
63569f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
63579f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
63585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
63599f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
63605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6361c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
636252e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6364c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
636623858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
63678a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    if (mCodec->getTrebleFlag()) {
6368ac7d4125516299b8a3e6f2b25822a692bdd96311Pawin Vongmasa        auto tOmxNode = omxNode->getHalInterface();
63698a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
63708a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            mDeathNotifier.clear();
63718a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        }
63728a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    } else {
63738a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
63748a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            // This was a local binder, if it dies so do we, we won't care
63758a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            // about any notifications in the afterlife.
63768a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            mDeathNotifier.clear();
63778a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        }
637823858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
637923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
638026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6381d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    notify->setInt32("generation", ++mCodec->mNodeGeneration);
6382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
638590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6386ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6387ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6388ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6389ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
63901713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
63910167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6392ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6393ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6395d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode = omxNode;
639679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str());
6397c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
64005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
64015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6404c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6405c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6406c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6407c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6409c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6411f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6412f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6413f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6414f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6415f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6416054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6417054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6418a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6419e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6420e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
64214e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
64226d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    mCodec->mGraphicBufferSource.clear();
6423054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6424c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6425c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6426c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6431c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
643254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6433f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6434f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6435c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6436c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6437c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6438c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
6439d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        (void)mCodec->mOMXNode->freeNode();
6440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6443c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
644454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
644579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        if (keepComponentAllocated) {
644679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onStopCompleted();
644779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        } else {
644879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onReleaseCompleted();
644979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        }
645054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
645154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6456c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6457c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6458c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6459c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6460c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6461c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6462c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6463c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6464c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
64657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
64667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
64677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
64687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
64697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
64707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
64717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
64728f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6473d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
64748f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6475d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6476d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6477d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6478d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6482c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6484c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6485c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6486c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6487c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6488c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6489c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6490c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6491c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
649254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6494c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6496c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
650179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onFlushCompleted();
6502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6504c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6506c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6507c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6508c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6509c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6510c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6511c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6512c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
65145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
65155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
65165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6517d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode != NULL);
65185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
65190806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
65205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
65210806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
65220806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
65230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
65240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
65250806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
65265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6527c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6528c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6529c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6530251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
65325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
653479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat);
6535c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6536c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
65375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
65385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6539d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6540addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (mCodec->mGraphicBufferSource == NULL) {
6541addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return BAD_VALUE;
6542addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6543addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6544addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    android_dataspace dataSpace;
6545addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err =
6546addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6547addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != OK) {
6548addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Failed to get default data space");
6549addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
6550addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6551addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6552addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    err = statusFromBinderStatus(
6553addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace));
6554addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != OK) {
6555addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("[%s] Unable to configure for node (err %d)",
6556addf2cbb120346ae42e78fa739245a353db5edadChong Zhang              mCodec->mComponentName.c_str(), err);
6557addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
6558addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6559a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6560d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
65616d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
65636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mRepeatFrameDelayUs));
6564a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6565a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6566a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6567a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
65686d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6569d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6570a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6571a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6572a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6573d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
65743604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        OMX_PARAM_U32TYPE maxPtsGapParams;
65753604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        InitOMXParams(&maxPtsGapParams);
65763604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        maxPtsGapParams.nPortIndex = kPortIndexInput;
65773604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs;
65783604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang
65793604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        err = mCodec->mOMXNode->setParameter(
65803604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang                (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
65813604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang                &maxPtsGapParams, sizeof(maxPtsGapParams));
658294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
658394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
658494ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
65856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6586d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
65872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
65882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
65892c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6590d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
65916d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65926d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
659337b2b389139ed638831e49708c947863eef631efRonghua Wu
659437b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
659537b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
65966d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6597d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
659837b2b389139ed638831e49708c947863eef631efRonghua Wu        }
659937b2b389139ed638831e49708c947863eef631efRonghua Wu    }
660037b2b389139ed638831e49708c947863eef631efRonghua Wu
660122dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) {
66026d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setTimeLapseConfig(
660422dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa                        mCodec->mFps, mCodec->mCaptureFps));
66052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
66062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
66072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
66086d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6609d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
66102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
66112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
661272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6613d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
66146d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
6615764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                mCodec->mGraphicBufferSource->setSuspend(true, -1));
661672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
661772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
661872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
66196d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6620d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
662194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
662294ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
662394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6624c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6625d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode->getParameter(
6626d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6627c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6628c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6629c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6630c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6631c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6632b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6633b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
66346d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
66356d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
66366d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
66376d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
66386d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66396d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
66406d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        *(ColorAspects *)colorAspectsBuffer->base())));
66416d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
6642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6643b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6644b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6645b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6646b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6647b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6648d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6649d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6650d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6651d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6652d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6653d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6654d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6655d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6656addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = mCodec->mOMX->createInputSurface(
6657addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            &bufferProducer, &mCodec->mGraphicBufferSource);
6658d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6659d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6660d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6661d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6662d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
66637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
666479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onInputSurfaceCreated(
666579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mInputFormat,
666679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mOutputFormat,
66677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
66687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
66697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
66707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
66717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
66727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
66737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
667479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onInputSurfaceCreationFailed(err);
66757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
66767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
66777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
667879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimvoid ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) {
66798f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6680d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6681d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6682d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6683d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6684addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    mCodec->mGraphicBufferSource = surface->getBufferSource();
6685d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6686addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = setupInputSurface();
6687b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6688b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
668979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onInputSurfaceAccepted(
669079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mInputFormat, mCodec->mOutputFormat);
6691addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    } else {
6692d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6693d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6694d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
66958f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6696d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
669779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onInputSurfaceDeclined(err);
6698d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6699d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6700d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6701c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
67025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
67035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6704d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
67050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
67060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
67070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
67080806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
67090806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6714f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6718f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
67193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6721cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6722cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
672329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6724cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6725cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6726cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6727251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
672891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6729d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mCodec->mOMXNode->sendCommand(
6730d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
6731c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6732c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6733c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6734c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6735c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6736c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6737c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
673891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6739cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6742f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6744dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (err != OK) {
6745dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        return err;
6746dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
6747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6748dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
6749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6753dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mCodec->mCallback->onStartCompleted();
6754dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
6755dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    return OK;
6756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6758f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
676072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
67686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
67696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
67706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
67716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
67726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
67736463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
67746463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
67756463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
67766463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
67776463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
67786463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
67796463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
67806463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
67816463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
678279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onFlushCompleted();
67836463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
67846463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
67856463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6791f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
67960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
67970806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
67980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
67990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
68000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
68010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
68020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
68030806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68050806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
6806d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mCodec->mOMXNode->sendCommand(
6807d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateExecuting);
68080806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68100806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
68110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
68120806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
68130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
68140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6826f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6830f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
68313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6834f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
683672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6843d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6844d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6845d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6846d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6847d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6848d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6849d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6850d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6851d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
685279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onFlushCompleted();
6853d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6854d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6855d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
68566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
68576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
68586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
68596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
68606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
68616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6867f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
68720806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
68730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
68740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
68750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
68760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
68770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
68790806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6894f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6895349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6896349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6899f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6900ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6904054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6905054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6906054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6908054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6909054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6910054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6911054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6913054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6914054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
69154dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
69164dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6917054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6918054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6919054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6920054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
69210806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
69260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
69270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
69280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
69290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
69300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
69310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
69370806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
69380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
69390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
69400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
69410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69440806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6945349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
694615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
69473fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        status_t err = mCodec->fillBuffer(info);
69480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
69490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
69500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
69510806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
69530806340688c937e7b78c2d89db3809274130df4eLajos Molnar
69540806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
69550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6959054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6960c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6961054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6962054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6963054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6964054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6966f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6967349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
69680806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6969349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6970349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6971349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69743cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6975777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6976777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6977777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6978777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
69793cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
69803cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
69813cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
69823cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
69833cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
69843cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6985349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6986349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6989f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
69903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
699290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
6994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6996f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7002c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
7003c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
7004c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
7005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
7006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
700754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
7008c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
7009c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
7010349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
7011349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7012d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(
7013d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateIdle);
70140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
70150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
70160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
70180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
70190806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
70200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
70210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
70297a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
7030ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
7031d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
7032d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
7033d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
7034d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
7035d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
7036d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7037349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
7038349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7039d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
70400806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
70410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70420806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
70430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
70440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
7051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
7053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7058496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
7059496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
7060496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
7061496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
7062496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
7063496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
7064496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7065496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
7066496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
7067496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
7068496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7069a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
7070a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
7071a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
7072a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
7073a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7074a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
7075a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7076a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
7077a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
7078a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
7079a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
7080a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
7081a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7082a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
7083a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
7084a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7085a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
70867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
70877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
70886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
70897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
70907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
70917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
70927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
70934dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7094054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
70954dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
70964dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
70974dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
7098054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
70994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
7100054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
71014dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
71024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
71034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
71044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
71054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
7106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7114a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
7115a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
7116530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
7117a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7118a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
7119a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
7120a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
7121a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7122d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->setConfig(
7123a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
7124a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
7125a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
7126a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7127a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
7128a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7129a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
7130a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7131a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
7132a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7133a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
7134a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
713561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    int64_t timeOffsetUs;
713661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
71376d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
71386d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set input buffer time offset without surface",
71396d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
71406d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
71416d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
71426d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
71436d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
71446d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
714561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
714661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        if (err != OK) {
714761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            ALOGE("[%s] Unable to set input buffer time offset (err %d)",
714861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                mComponentName.c_str(),
714961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                err);
715061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            return err;
715161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
715261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    }
715361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
715472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
715572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
71566d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
71576d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set start time without surface",
71586d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
71596d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
71606d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
71616d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
71626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
71636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
716472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
716572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
716672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
716772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
716872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
716972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
717072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7171e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
7172e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
71736d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
71746d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set suspend without surface",
71756d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
71766d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
71776d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
7178e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
7179764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        int64_t suspendStartTimeUs = -1;
7180764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs);
71816d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
7182764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs));
7183b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7184b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7185b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7186b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7187b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7188b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
7189b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7190764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    int64_t stopTimeUs;
7191764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (params->findInt64("stop-time-us", &stopTimeUs)) {
7192764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (mGraphicBufferSource == NULL) {
7193764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGE("[%s] Invalid to set stop time without surface",
7194764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    mComponentName.c_str());
7195764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            return INVALID_OPERATION;
7196764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
7197764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        status_t err = statusFromBinderStatus(
7198764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                mGraphicBufferSource->setStopTimeUs(stopTimeUs));
7199764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
7200764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (err != OK) {
7201764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err);
7202764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            return err;
7203764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
7204764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
7205764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
7206b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7207b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7208b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7209b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7210b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7211b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7212b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7213b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7214e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7215e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
72168db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
72178db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
72188db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
72198db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
72208db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
72218db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
72228db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
72238db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
72248db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7225870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7226870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7227870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7228870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7229870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7230870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7231870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7232870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7233870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7234870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7235870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
723689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    int32_t latency = 0;
723789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    if (params->findInt32("latency", &latency) && latency > 0) {
723889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        status_t err = setLatency(latency);
723989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        if (err != OK) {
724089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            ALOGI("[%s] failed setLatency. Failure is fine since this key is optional",
724189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                    mComponentName.c_str());
724289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            err = OK;
724389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        }
724489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    }
724589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
72460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
72470f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
72480f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        err = OK; // ignore failure
72490f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
72500f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
725101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    return setVendorParameters(params);
725201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar}
725301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
725401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
725501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// the minimum number of characters to keep in |key| (even if it has trailing tags).
725601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// (Used to remove trailing 'value' tags in settings names, e.g. to normalize
725701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// 'vendor.settingsX.value' to 'vendor.settingsX')
725801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarstatic void removeTrailingTags(char *key, size_t minLength, const char *tag) {
725901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    size_t length = strlen(key);
726001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    size_t tagLength = strlen(tag);
726101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    while (length > minLength + tagLength
726201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            && !strcmp(key + length - tagLength, tag)
726301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            && key[length - tagLength - 1] == '.') {
726401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        length -= tagLength + 1;
726501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        key[length] = '\0';
726601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
726701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar}
726801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
726901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar/**
727001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar * Struct encompassing a vendor extension config structure and a potential error status (in case
727101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar * the structure is null). Used to iterate through vendor extensions.
727201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar */
727301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarstruct VendorExtension {
727401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config;  // structure does not own config
727501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    status_t status;
727601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
727701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // create based on an error status
727801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { }
727901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
728001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // create based on a successfully retrieved config structure
728101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { }
728201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar};
728301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
728401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// class VendorExtensions;
728501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar/**
728601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar * Forward iterator to enumerate vendor extensions supported by an OMX component.
728701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar */
728801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarclass VendorExtensionIterator {
728901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar//private:
729001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    static constexpr size_t kLastIndex = ~(size_t)0; // last index marker
729101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
729201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    sp<IOMXNode> mNode;                   // component
729301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    size_t mIndex;                        // current android extension index
729401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    std::unique_ptr<uint8_t[]> mBacking;  // current extension's backing
729501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension mCurrent;             // current extension
729601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
729701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator(const sp<IOMXNode> &node, size_t index)
729801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        : mNode(node),
729901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar          mIndex(index) {
730001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mCurrent = retrieve();
730101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
730201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
730301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    friend class VendorExtensions;
730401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
730501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarpublic:
730601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // copy constructor
730701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator(const VendorExtensionIterator &it)
730801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        : VendorExtensionIterator(it.mNode, it.mIndex) { }
730901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
731001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // retrieves the current extension pointed to by this iterator
731101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension retrieve() {
731201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (mIndex == kLastIndex) {
731301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return NO_INIT;
731401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
731501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
731601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        // try with one param first, then retry if extension needs more than 1 param
731701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        for (size_t paramSizeUsed = 1;; ) {
731801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) {
731901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return BAD_VALUE; // this prevents overflow in the following formula
732001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
732101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
732201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) +
732301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param);
732401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            mBacking.reset(new uint8_t[size]);
732501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (!mBacking) {
732601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return NO_MEMORY;
732701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
732801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
732901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config =
733001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get());
733101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
733201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            InitOMXParams(config);
733301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->nSize = size;
733401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->nIndex = mIndex;
733501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->nParamSizeUsed = paramSizeUsed;
733601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            status_t err = mNode->getConfig(
733701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size);
733801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) {
733901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // reallocate if we need a bigger config
734001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                paramSizeUsed = config->nParamCount;
734101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                continue;
734201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            } else if (err == NOT_ENOUGH_DATA
734301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                   || (err != OK && mIndex == 0)) {
734401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // stop iterator on no-more signal, or if index is not at all supported
734501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                mIndex = kLastIndex;
734601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return NO_INIT;
734701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            } else if (err != OK) {
734801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return err;
734901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            } else if (paramSizeUsed != config->nParamSizeUsed) {
735001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return BAD_VALUE; // component shall not modify size of nParam
735101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
735201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
735301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return config;
735401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
735501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
735601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
735701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // returns extension pointed to by this iterator
735801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension operator*() {
735901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return mCurrent;
736001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
736101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
736201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // prefix increment: move to next extension
736301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator &operator++() { // prefix
736401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (mIndex != kLastIndex) {
736501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            ++mIndex;
736601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            mCurrent = retrieve();
736701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
736801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return *this;
736901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
737001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
737101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // iterator equality operators
737201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    bool operator==(const VendorExtensionIterator &o) {
737301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return mNode == o.mNode && mIndex == o.mIndex;
737401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
737501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
737601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    bool operator!=(const VendorExtensionIterator &o) {
737701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return !(*this == o);
737801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
737901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar};
738001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
738101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar/**
738201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar * Iterable container for vendor extensions provided by a component
738301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar */
738401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarclass VendorExtensions {
738501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar//private:
738601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    sp<IOMXNode> mNode;
738701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
738801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarpublic:
738901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensions(const sp<IOMXNode> &node)
739001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        : mNode(node) {
739101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
739201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
739301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator begin() {
739401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return VendorExtensionIterator(mNode, 0);
739501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
739601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
739701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator end() {
739801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex);
739901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
740001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar};
740101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
740201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarstatus_t ACodec::setVendorParameters(const sp<AMessage> &params) {
740301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name
740401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    constexpr char prefix[] = "vendor.";
740501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    constexpr size_t prefixLength = sizeof(prefix) - 1;
740601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // longest possible vendor param name
740701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE];
740801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
740901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // identify all vendor keys to speed up search later and to detect vendor keys
741001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    for (size_t i = params->countEntries(); i; --i) {
741101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        AMessage::Type keyType;
741201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        const char* key = params->getEntryNameAt(i - 1, &keyType);
741301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (key != nullptr && !strncmp(key, prefix, prefixLength)
741401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // it is safe to limit format keys to the max vendor param size as we only
741501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // shorten parameter names by removing any trailing 'value' tags, and we
741601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // already remove the vendor prefix.
741701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                && strlen(key + prefixLength) < sizeof(reducedKey)
741801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                && (keyType == AMessage::kTypeInt32
741901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                        || keyType == AMessage::kTypeInt64
742001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                        || keyType == AMessage::kTypeString)) {
742101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            strcpy(reducedKey, key + prefixLength);
742201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            removeTrailingTags(reducedKey, 0, "value");
742301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            auto existingKey = vendorKeys.find(reducedKey);
742401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (existingKey != vendorKeys.end()) {
742501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'",
742601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                        mComponentName.c_str(), key, existingKey->second.c_str());
742701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // ignore for now
742801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
742901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            vendorKeys.emplace(reducedKey, key);
743001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
743101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
743201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
743301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // don't bother component if we don't have vendor extensions as they may not have implemented
743401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // the android vendor extension support, which will lead to unnecessary OMX failure logs.
743501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (vendorKeys.empty()) {
743601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return OK;
743701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
743801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
743901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
744001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)];
744101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
744201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    status_t finalError = OK;
744301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
744401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // don't try again if component does not have vendor extensions
744501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (mVendorExtensionsStatus == kExtensionsNone) {
744601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return OK;
744701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
744801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
744901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    for (VendorExtension ext : VendorExtensions(mOMXNode)) {
745001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
745101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (config == nullptr) {
745201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return ext.status;
745301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
745401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
745501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mVendorExtensionsStatus = kExtensionsExist;
745601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
745701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
745801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        strcpy(key, (const char *)config->cName);
745901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        size_t nameLength = strlen(key);
746001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        key[nameLength] = '.';
746101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
746201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        // don't set vendor extension if client has not provided any of its parameters
746301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        // or if client simply unsets parameters that are already unset
746401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        bool needToSet = false;
746501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
746601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            // null-terminate param key
746701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
746801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
746901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            removeTrailingTags(key, nameLength, "value");
747001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            auto existingKey = vendorKeys.find(key);
747101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
747201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            // don't touch (e.g. change) parameters that are not specified by client
747301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (existingKey == vendorKeys.end()) {
747401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                continue;
747501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
747601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
747701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            bool wasSet = config->param[paramIndex].bSet;
747801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            switch (config->param[paramIndex].eValueType) {
747901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            case OMX_AndroidVendorValueInt32:
748001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            {
748101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                int32_t value;
748201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                config->param[paramIndex].bSet =
748301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value);
748401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                if (config->param[paramIndex].bSet) {
748501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    config->param[paramIndex].nInt32 = value;
748601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
748701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                break;
748801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
748901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            case OMX_AndroidVendorValueInt64:
749001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            {
749101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                int64_t value;
749201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                config->param[paramIndex].bSet =
749301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value);
749401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                if (config->param[paramIndex].bSet) {
749501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    config->param[paramIndex].nInt64 = value;
749601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
749701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                break;
749801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
749901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            case OMX_AndroidVendorValueString:
750001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            {
750101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                AString value;
750201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                config->param[paramIndex].bSet =
750301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_BOOL)params->findString(existingKey->second.c_str(), &value);
750401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                if (config->param[paramIndex].bSet) {
750501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    strncpy((char *)config->param[paramIndex].cString, value.c_str(),
750601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cString));
750701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
750801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                break;
750901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
751001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            default:
751101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                ALOGW("[%s] vendor parameter '%s' is not a supported value",
751201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                        mComponentName.c_str(), key);
751301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                continue;
751401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
751501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (config->param[paramIndex].bSet || wasSet) {
751601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                needToSet = true;
751701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
751801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
751901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
752001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (needToSet) {
752101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            status_t err = mOMXNode->setConfig(
752201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension,
752301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    config, config->nSize);
752401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (err != OK) {
752501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                key[nameLength] = '\0';
752601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key);
752701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // try to set each extension, and return first failure
752801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                if (finalError == OK) {
752901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    finalError = err;
753001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
753101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
753201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
753301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
753401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
753501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (mVendorExtensionsStatus == kExtensionsUnchecked) {
753601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mVendorExtensionsStatus = kExtensionsNone;
753701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
753801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
753901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    return finalError;
754001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar}
754101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
754201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarstatus_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) {
754301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    constexpr char prefix[] = "vendor.";
754401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    constexpr size_t prefixLength = sizeof(prefix) - 1;
754501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
754601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength];
754701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    strcpy(key, prefix);
754801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
754901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // don't try again if component does not have vendor extensions
755001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (mVendorExtensionsStatus == kExtensionsNone) {
755101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return OK;
755201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
755301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
755401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    for (VendorExtension ext : VendorExtensions(mOMXNode)) {
755501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
755601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (config == nullptr) {
755701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return ext.status;
755801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
755901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
756001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mVendorExtensionsStatus = kExtensionsExist;
756101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
756201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) {
756301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            continue;
756401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
756501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
756601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
756701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        strcpy(key + prefixLength, (const char *)config->cName);
756801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        size_t nameLength = strlen(key);
756901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        key[nameLength] = '.';
757001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
757101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
757201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            // null-terminate param key
757301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
757401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
757501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            removeTrailingTags(key, nameLength, "value");
757601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (config->param[paramIndex].bSet) {
757701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                switch (config->param[paramIndex].eValueType) {
757801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                case OMX_AndroidVendorValueInt32:
757901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                {
758001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    format->setInt32(key, config->param[paramIndex].nInt32);
758101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    break;
758201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
758301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                case OMX_AndroidVendorValueInt64:
758401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                {
758501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    format->setInt64(key, config->param[paramIndex].nInt64);
758601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    break;
758701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
758801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                case OMX_AndroidVendorValueString:
758901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                {
759001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0';
759101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    format->setString(key, (const char *)config->param[paramIndex].cString);
759201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    break;
759301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
759401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                default:
759501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    ALOGW("vendor parameter %s is not a supported value", key);
759601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    continue;
759701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
759801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
759901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
760001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
760101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
760201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (mVendorExtensionsStatus == kExtensionsUnchecked) {
760301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mVendorExtensionsStatus = kExtensionsNone;
760401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
760501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
760601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    return OK;
7607a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7608a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
76096507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
76106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err = INVALID_OPERATION;
76116d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (mGraphicBufferSource != NULL) {
76126d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
76136d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
761479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCallback->onSignaledInputEOS(err);
76156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
76166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
761790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
761890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
761990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
762090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
762190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7622f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7629b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7630b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
763131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7632054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7633d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                CHECK_EQ(mCodec->mOMXNode->sendCommand(
7634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7637349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7640b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7641b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7642ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7661f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7666f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7677f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7684349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7685e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7687349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
76883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7689349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7690349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7704f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
77053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
770990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
771090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
771190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
771290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
771390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
771490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7715f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
77210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
77220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
77230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
77240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
77290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
77300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
77310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
77320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
77330806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
77348a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    if (mCodec->getTrebleFlag()) {
77358a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        mCodec->mAllocator[kPortIndexOutput].clear();
77368a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    } else {
77378a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        mCodec->mDealer[kPortIndexOutput].clear();
77388a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    }
77390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
7742d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mCodec->mOMXNode->sendCommand(
7743d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_CommandPortEnable, kPortIndexOutput);
77440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
77470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
77480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
77490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
7750dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    mCodec->mCallback->onOutputBuffersChanged();
77510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7752cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
77530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7754251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7755d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7756755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7757755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7758755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7759755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7760755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7761755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7762755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7763755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7764cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7768777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7769777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7770777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7771777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
77730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7775349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7776349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7777349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7778349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7794f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
77955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
77965778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7799f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
78070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7813349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang            mCodec->deferMessage(msg);
7814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7826f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
78273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
782831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
78295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7830b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7833f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
78380806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
78390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
78400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
78410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
78420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
78430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
78440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
78450806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
78485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7854349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7855349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7856349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7857349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7858349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7859349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7860349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
78650af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7866f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
78675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
7868d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mCodec->mOMXNode->sendCommand(
7869d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
78700806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
78710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
78720806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
78730806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
78740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
78750806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
78760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78780167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
78790167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7880bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7881bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7882bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7883bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7884b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7885bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7886bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
78870806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
78880806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
78890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
78900806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
78910806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7896f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7903f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7912f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7916f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7922349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang            mCodec->deferMessage(msg);
7923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
79310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7943f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
79443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7947f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
79520806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
79530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
79540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
79550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
79560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
79570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
79580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
79590806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7961c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7973f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7977f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
79783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7983f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
8001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
8002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
8003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
8006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8008f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
8009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8010ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
8011ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
8012d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
8013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
8014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
8015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
80160806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
80170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
80180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
80190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
80200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
80210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
8022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
8024777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
8025777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
8026777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
8027777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
8028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
8029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
8030e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
80310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
8032e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
8033e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
8034777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
8035777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
8036777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
8037777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
8038777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
8039777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
8040777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
8041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
8043777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
8044777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
8045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
8046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
8048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
8049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8050349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
8051349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
80521d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
8053349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
8054d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            msg->setInt32("generation", mCodec->mNodeGeneration);
8055349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
8056349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
8057349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
8058349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
80593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
8060349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
8061349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
8062349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
8063349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
8064349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
8065349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
8066349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
8067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
8068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
8069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
8072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8074f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
8075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
8076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
8078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8080f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
8081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
8082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
8084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8086f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
8087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
8088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
8089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
80907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
80917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
80927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
80937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
809490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
809590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
809679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onFlushCompleted();
8097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
8099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
8100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8101dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
8102dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
8103f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
8104f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
8105f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
8106f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
8107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
8108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
81125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
81135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
81145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
81151ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime.c_str());
81165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
81175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
81185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
81195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
81205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
81219c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    status_t err = client.connect();
81225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
81235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
81245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
81255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
81265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
81275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
8128d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
81295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
81301d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang    err = omx->allocateNode(name.c_str(), observer, &omxNode);
81315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
81325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
81335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
81345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
81355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
8136d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = SetComponentRole(omxNode, role);
81375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
8138d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode->freeNode();
81395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
81405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
81415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
81425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
81435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
81445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
81455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
81465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
81475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
81485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
81495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
81505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
81516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
81526e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
8153d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
8154d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoProfileLevelQuerySupported,
81555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
81565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
81575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
81585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
81595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
81606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
81616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
81626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
81636e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
81646e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
81656e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
81665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
81675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
81685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
81695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
81705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
81715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
81725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
817336e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
81745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
81756e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
81766e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
8177d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
8178d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoPortFormat,
81795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
81805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
81815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
81825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
81835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
81845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
81851ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim            if (IsFlexibleColorFormat(
8186d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
81875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
81885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
81895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
81905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
81915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
81925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
81935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
81945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
81955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
81965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
81975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
81985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
81995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
82005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
82015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
82026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
82036e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
82046e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
82056e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
82066e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
82076e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
82085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
82095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
82105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
82115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
82125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
82135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
82146e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
82156e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
8216d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
8217d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
82185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
82195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
82205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
82215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
82225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
82235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
82246e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
82256e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
82266e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
82276e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
82286e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
82296e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
82305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
82315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
82325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
82335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
82345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
82355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
82365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
82375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
82385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
82395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
82405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
8241d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->configureVideoTunnelMode(
8242d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
82435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
82445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
82455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
8246d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else if (omxNode->setPortMode(
8247d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
8248d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                omxNode->prepareForAdaptivePlayback(
8249d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE,
82505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
82515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
82525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
82535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
82545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
82555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
82565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
82575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
82585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
82595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
8260d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->getConfig(
8261d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
82625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
82635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
82645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
82655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
82665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
82675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
8268d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    omxNode->freeNode();
82695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
82705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
82715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
82725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
8273a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
8274a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
8275a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
8276a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
8277a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
8278a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
8279a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
8280a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8281a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
8282a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8283a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8284a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8285a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
8286a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8287a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8288a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8289a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8290a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
8291a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8292a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8293a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
8294a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
8295a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8296a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
8297a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8298a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8299a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8300a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
8301a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
8302a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8303a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
8304a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8305a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8306a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8307a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
8308a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
8309a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
8310a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8311a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
8312a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8313a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8314a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8315a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
8316a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
8317a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
8318a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
8319a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8320a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
8321a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8322a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8323a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8324a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
8325a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
8326a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
8327a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
8328a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
8329a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8330a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
8331a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
8332a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
8333a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
8334a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
8335a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
8336a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
83379c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasavoid ACodec::setTrebleFlag(bool trebleFlag) {
83389c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    mTrebleFlag = trebleFlag;
83398a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa}
83408a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
83418a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasabool ACodec::getTrebleFlag() const {
83428a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    return mTrebleFlag;
83438a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa}
83448a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
8345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
8346