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
2544ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    virtual void stateExited();
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
26526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
26926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
27026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
27126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
27226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
27326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
27415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
28015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
28115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
28490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2928a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasastruct ACodec::DeathNotifier :
2938a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        public IBinder::DeathRecipient,
2948a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        public ::android::hardware::hidl_death_recipient {
295090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit DeathNotifier(const sp<AMessage> &notify)
296ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
297ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
298ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
299ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
300ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
301ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
302ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3038a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    virtual void serviceDied(
3048a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            uint64_t /* cookie */,
3058a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
3068a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        mNotify->post();
3078a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    }
3088a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
309ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
310ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
311ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
312ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
313ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
314ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
315ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
316ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
317ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
319090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit UninitializedState(ACodec *codec);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
330ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
336c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
337090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedState(ACodec *codec);
338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
340c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
343c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
345c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3488f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
350c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
352d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
353d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
354c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
355c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
356c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
358c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
360090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedToIdleState(ACodec *codec);
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
376090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToExecutingState(ACodec *codec);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
390090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingState(ACodec *codec);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
393054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
401349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
40990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
412349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
413349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
420090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit OutputPortSettingsChangedState(ACodec *codec);
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
42890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
437090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingToIdleState(ACodec *codec);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
459090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToLoadedState(ACodec *codec);
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
474090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit FlushingState(ACodec *codec);
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
49615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
49715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
49815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
49915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
50115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
50215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
50315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
50415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
50515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
50615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
50715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
50815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
51015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
51115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
51215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
51315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
51415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
51515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
51615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
51715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
51815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
51915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
52015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
52115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
52215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
52315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
52415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
52515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
52615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
527f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
528b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    : mSampleRate(0),
529d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang      mNodeGeneration(0),
530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
531e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
532fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
5338db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
535346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5369806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
53754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
538f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang      mIsLegacyVP9Decoder(false),
5399806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5409806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
541e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5429806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
543054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
544054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
545054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
54794ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
54937b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
55022dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa      mFps(-1.0),
55122dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa      mCaptureFps(-1.0),
552ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
55389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang      mLatency(0),
5548338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
555db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
55601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
5574ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim      mStateGeneration(0),
55801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar      mVendorExtensionsStatus(kExtensionsUnchecked) {
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
560c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
573dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
576d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
577d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
578fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
579fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
5818a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
5829c47c97ecac581d66b6febafd156618247e86742Pawin Vongmasa    mTrebleFlag = false;
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
585f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
588f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
594dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstd::shared_ptr<BufferChannelBase> ACodec::getBufferChannel() {
595dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (!mBufferChannel) {
596dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel = std::make_shared<ACodecBufferChannel>(
597dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                new AMessage(kWhatInputBufferFilled, this),
598dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                new AMessage(kWhatOutputBufferDrained, this));
599dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
600dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    return mBufferChannel;
601dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
602dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
603a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
6041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
605a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
606a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
607a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
608a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6095778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
6111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6155778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
6171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
6221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
6231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
6241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
6261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
6271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
6321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
6351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
6367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6388f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
639d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
6408f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
641d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
642d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
643d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
644d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6495778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6501d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
653f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6547a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
658f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6631d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
665c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
66630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
66730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
66930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
672496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
674496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
675496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6794dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6804dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
681054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
683054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
684054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6864dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6874dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
698e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
7001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
7011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
7021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
7051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
717e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
718098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    // no need to reconnect as we will not dequeue all buffers
719098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(
720d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            nativeWindow, &usageBits, !storingMetadataInDecodedBuffers());
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
725f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
726e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
727e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
728e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
729e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
730e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
731e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
7361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
7371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
7451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
761dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
762dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
763dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
769054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
771598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa            ALOGV("skipping buffer");
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
786d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (!storingMetadataInDecodedBuffers()) {
7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
78815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
79215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
79315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
8001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
8011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
8021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
8031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
8041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
806484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
807484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
808484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
809484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
810484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
8111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
812e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
8131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
8141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
816d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhangstatus_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
817d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    status_t err = mOMXNode->setPortMode(portIndex, mode);
818d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK) {
819d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
820d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                mComponentName.c_str(),
821d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                portIndex == kPortIndexInput ? "input" : "output",
822d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                asString(mode),
823d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                err);
824d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        return err;
825d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    }
826d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
827d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[portIndex] = mode;
828d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    return OK;
829d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang}
830d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8348a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    if (getTrebleFlag()) {
8358a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        CHECK(mAllocator[portIndex] == NULL);
8368a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    } else {
8378a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        CHECK(mDealer[portIndex] == NULL);
8388a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    }
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
843d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (storingMetadataInDecodedBuffers()) {
844054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
854d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
857d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            const IOMX::PortMode &mode = mPortMode[portIndex];
8585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
859d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // Always allocate VideoNativeMetadata if using ANWBuffer.
860d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // OMX might use gralloc source internally, but we don't share
861d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // metadata buffer with OMX, OMX has its own headers.
862d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mode == IOMX::kPortModeDynamicANWBuffer) {
863054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
864d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            } else if (mode == IOMX::kPortModeDynamicNativeHandle) {
8653e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                bufSize = sizeof(VideoNativeHandleMetadata);
866054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
867054219874873b41f1c815552987c10465c34ba2bLajos Molnar
8685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
878054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
879054219874873b41f1c815552987c10465c34ba2bLajos Molnar
88028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
88128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
882d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
884d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode),
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
8885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
88928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
89028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
89128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
89228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
89328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
89428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
8955b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
8965b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
89734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
89834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
89934e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
90028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
901d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mode != IOMX::kPortModePresetSecureBuffer) {
9028a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                if (getTrebleFlag()) {
9038a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    mAllocator[portIndex] = TAllocator::getService("ashmem");
9048a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                    if (mAllocator[portInde