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
31d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang#include <media/stagefright/foundation/avc_utils.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
36a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
3990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar#include <media/stagefright/MediaCodec.h>
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
42d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
43b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
45bc8f53b8c1c220d9ce01526b6e3834f14af98ed5Dongwon Kang#include <media/MediaBufferHolder.h>
463fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang#include <media/OMXBuffer.h>
47ac7d4125516299b8a3e6f2b25822a692bdd96311Pawin Vongmasa#include <media/omx/1.0/WOmxNode.h>
483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
498a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa#include <hidlmemory/mapping.h>
508a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
51255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_AudioExt.h>
52255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_VideoExt.h>
53255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_Component.h>
54255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_IndexExt.h>
55255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/openmax/OMX_AsString.h>
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include "include/ACodecBufferChannel.h"
585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar#include "include/DataConverter.h"
594811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim#include "include/SecureBuffer.h"
607e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include "include/SharedMemoryBuffer.h"
61255735a38b9d5c3755c7b819bdc8fdaf4357d860Pawin Vongmasa#include <media/stagefright/omx/OMXUtils.h>
62496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
656d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangusing binder::Status;
666d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnarenum {
686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
696e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar};
706e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
99251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
1006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangstatic inline status_t statusFromBinderStatus(const Status &status) {
1016d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (status.isOk()) {
1026d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return OK;
1036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1046d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err;
1056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.serviceSpecificErrorCode()) != OK) {
1066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1076d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1086d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.transactionError()) != OK) {
1096d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1116d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Other exception
1126d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return UNKNOWN_ERROR;
1136d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
1146d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
117251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
128456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhangstatic OMX_VIDEO_CONTROLRATETYPE getVideoBitrateMode(const sp<AMessage> &msg) {
129456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    int32_t tmp;
130456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    if (msg->findInt32("bitrate-mode", &tmp)) {
131456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        // explicitly translate from MediaCodecInfo.EncoderCapabilities.
132456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        // BITRATE_MODE_* into OMX bitrate mode.
133456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        switch (tmp) {
134456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            //BITRATE_MODE_CQ
135456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            case 0: return OMX_Video_ControlRateConstantQuality;
136456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            //BITRATE_MODE_VBR
137456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            case 1: return OMX_Video_ControlRateVariable;
138456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            //BITRATE_MODE_CBR
139456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            case 2: return OMX_Video_ControlRateConstant;
140456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            default: break;
141456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        }
142456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    }
143456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    return OMX_Video_ControlRateVariable;
144456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang}
145456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang
146456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhangstatic bool findVideoBitrateControlInfo(const sp<AMessage> &msg,
147456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        OMX_VIDEO_CONTROLRATETYPE *mode, int32_t *bitrate, int32_t *quality) {
148456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    *mode = getVideoBitrateMode(msg);
149456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    bool isCQ = (*mode == OMX_Video_ControlRateConstantQuality);
150456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    return (!isCQ && msg->findInt32("bitrate", bitrate))
151456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang         || (isCQ && msg->findInt32("quality", quality));
152456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang}
153456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang
15426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
15526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
15626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
157984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    virtual ~MessageList() {
158984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    }
15926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
16126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
16226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
16326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
16426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
16526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
1665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnarstatic sp<DataConverter> getCopyConverter() {
1675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
1685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static sp<DataConverter> sCopyConverter;        // zero-inited
1695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
1705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return sCopyConverter;
1715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar}
1725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
18126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
182984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        if (messages.empty()) {
183984a54322f7c70bc75e862d91bdd975814872affLajos Molnar            return;
184984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        }
185984a54322f7c70bc75e862d91bdd975814872affLajos Molnar
186984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        sp<AMessage> notify = mNotify->dup();
18726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
18826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
18926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
19026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
19226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
19326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
19426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
19526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
19626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
19726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
19826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
19926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
20026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
20126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
20426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
20526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
20626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
20726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
20826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
21126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
21226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
21326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
21426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
21526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
21626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
21726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
21826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
21926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
22026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
22126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
22226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
22326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
22426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
22526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
22626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
22726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
22826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
22926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
23290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
23390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
23490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
23590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
23690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
23790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
23890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
23990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
24026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
24126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
24226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
24326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
24426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
24526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
24626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
24726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
262090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2754ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    virtual void stateExited();
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
28626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
29026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
29126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
29226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
29326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
29426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
29515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
30115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
30215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
30590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3138a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasastruct ACodec::DeathNotifier :
3148a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        public IBinder::DeathRecipient,
3158a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        public ::android::hardware::hidl_death_recipient {
316090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit DeathNotifier(const sp<AMessage> &notify)
317ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
318ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
319ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
320ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
321ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
322ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
323ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3248a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    virtual void serviceDied(
3258a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            uint64_t /* cookie */,
3268a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa            const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
3278a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa        mNotify->post();
3288a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa    }
3298a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa
330ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
331ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
332ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
333ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
334ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
335ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
336ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
337ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
338ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
340090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit UninitializedState(ACodec *codec);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
351ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
358090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedState(ACodec *codec);
359c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
360c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
366c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
367c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3698f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
370c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
371c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
372c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
373d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
374d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
376c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
377c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
378c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
379c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
381090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedToIdleState(ACodec *codec);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
397090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToExecutingState(ACodec *codec);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
411090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingState(ACodec *codec);
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
413054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
414054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
421349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
422349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
423349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
43090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
433349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
434349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
441090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit OutputPortSettingsChangedState(ACodec *codec);
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
44990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
458090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingToIdleState(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 Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
480090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToLoadedState(ACodec *codec);
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
482f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
495090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit FlushingState(ACodec *codec);
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
51715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
51815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
51915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
52015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
52115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
52215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
52315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
52415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
52515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
52615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
52715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
52815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
52915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
53015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
53115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
53215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
53315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
53415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
53515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
53615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
53715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
53815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
53915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
54015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
54115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
54215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
54315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
54415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
54515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
54615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
54715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
548f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
549b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    : mSampleRate(0),
550d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang      mNodeGeneration(0),
551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
552e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
553fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
5548db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
555816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang      mIsImage(false),
556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
557346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5589806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
55954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
560f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang      mIsLegacyVP9Decoder(false),
5619806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5629806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
563e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5649806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
565054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
566054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
567054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
56994ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5706c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang      mMaxPtsGapUs(0ll),
57137b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
57222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa      mFps(-1.0),
57322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa      mCaptureFps(-1.0),
574ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
57589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang      mLatency(0),
5768338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
577db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
57801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
5794ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim      mStateGeneration(0),
58001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar      mVendorExtensionsStatus(kExtensionsUnchecked) {
5812d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang    memset(&mLastHDRStaticInfo, 0, sizeof(mLastHDRStaticInfo));
5822d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
584c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
597dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
599d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
600d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
601d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
602fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
603fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
610f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
6121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
616dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstd::shared_ptr<BufferChannelBase> ACodec::getBufferChannel() {
617dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (!mBufferChannel) {
618dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel = std::make_shared<ACodecBufferChannel>(
619dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                new AMessage(kWhatInputBufferFilled, this),
620dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                new AMessage(kWhatOutputBufferDrained, this));
621dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
622dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    return mBufferChannel;
623dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
624dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
625a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
6261d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
627a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
628a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
629a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
630a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6315778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
6325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
6331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
6345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
6355778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6375778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
6385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
6391d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
6405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
6415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
6521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
6571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
6587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6608f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
661d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
6628f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
663d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
664d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
665d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
666d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6715778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
675f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6767a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6771d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
680f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6811d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
68830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
68930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
69130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
694496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
696496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
697496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6984dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
7004dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
7014dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
7024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
703054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
7044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
705054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
706054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
7074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
7084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
7094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
720e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
7361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
7371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
739e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
740098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    // no need to reconnect as we will not dequeue all buffers
741098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(
742d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            nativeWindow, &usageBits, !storingMetadataInDecodedBuffers());
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
747f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
748e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
749e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
750e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
751e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
752e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
753e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
7601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
7621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
7631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
7661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
7671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
783dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
784dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
785dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
791054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
7921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
793598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa            ALOGV("skipping buffer");
7941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
8001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
8011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
8021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
8031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
8041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
8051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
808d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (!storingMetadataInDecodedBuffers()) {
8091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
81015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
8111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
8121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
8131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
81415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
81515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
8161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
8171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
8181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
8191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
8201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
8211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
8221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
8231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
8241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
8251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
8261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
828484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
829484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
830484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
831484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
832484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
8331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
834e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
8351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
8361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
838d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhangstatus_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
839d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    status_t err = mOMXNode->setPortMode(portIndex, mode);
840d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK) {
841d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
842d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                mComponentName.c_str(),
843d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                portIndex == kPortIndexInput ? "input" : "output",
844d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                asString(mode),
845d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                err);
846d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        return err;
847d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    }
848d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
849d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[portIndex] = mode;
850d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    return OK;
851d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang}
852d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
856e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa    CHECK(mAllocator[portIndex] == NULL);
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
861d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (storingMetadataInDecodedBuffers()) {
862054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
8665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
8685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
8695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
871d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
872d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
875d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            const IOMX::PortMode &mode = mPortMode[portIndex];
8765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
877d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // Always allocate VideoNativeMetadata if using ANWBuffer.
878d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // OMX might use gralloc source internally, but we don't share
879d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // metadata buffer with OMX, OMX has its own headers.
880d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mode == IOMX::kPortModeDynamicANWBuffer) {
881054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
882d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            } else if (mode == IOMX::kPortModeDynamicNativeHandle) {
8833e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                bufSize = sizeof(VideoNativeHandleMetadata);
884054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
885054219874873b41f1c815552987c10465c34ba2bLajos Molnar
8865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8955b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
896054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
897054219874873b41f1c815552987c10465c34ba2bLajos Molnar
898e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa            size_t alignment = 32; // This is the value currently returned by
899e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                   // MemoryDealer::getAllocationAlignment().
900e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                   // TODO: Fix this when Treble has
901e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                   // MemoryHeap/MemoryDealer.
90228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
903d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
905d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode),
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
9095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
91028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
91128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
91228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
91328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
91428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
91528edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
9165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
9175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
91834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
91934e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
92034e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
92128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
922d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mode != IOMX::kPortModePresetSecureBuffer) {
923e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                mAllocator[portIndex] = TAllocator::getService("ashmem");
924e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                if (mAllocator[portIndex] == nullptr) {
925e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    ALOGE("hidl allocator on port %d is null",
926e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                            (int)portIndex);
927e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    return NO_MEMORY;
9288a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                }
929e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                // TODO: When Treble has MemoryHeap/MemoryDealer, we should
930e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                // specify the heap size to be
931e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                // def.nBufferCountActual * (alignedSize + alignedConvSize).
932d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            }
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
934fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            const sp<AMessage> &format =
935fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                    portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
936054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
9378a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                hidl_memory hidlMemToken;
9388a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                sp<TMemory> hidlMem;
939d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                sp<IMemory> mem;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
941ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
942ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
94315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
94490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
9451b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                info.mGraphicBuffer = NULL;
9461b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                info.mNewGraphicBuffer = false;
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
948d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                if (mode == IOMX::kPortModePresetSecureBuffer) {
949a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
9501b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    sp<NativeHandle> native_handle;
951d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->allocateSecureBuffer(
952d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            portIndex, bufSize, &info.mBufferID,
953a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
954a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
9554811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                    info.mData = (native_handle == NULL)
9564811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            ? new SecureBuffer(format, ptr, bufSize)
9574811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            : new SecureBuffer(format, native_handle, bufSize);
9585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = info.mData;
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
960e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    bool success;
961e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    auto transStatus = mAllocator[portIndex]->allocate(
962e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                            bufSize,
963e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                            [&success, &hidlMemToken](
964e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                    bool s,
965e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                    hidl_memory const& m) {
966e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                success = s;
967e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                hidlMemToken = m;
968e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                            });
969e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa
970e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    if (!transStatus.isOk()) {
971e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        ALOGE("hidl's AshmemAllocator failed at the "
972e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                "transport: %s",
973e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                transStatus.description().c_str());
974e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        return NO_MEMORY;
975e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    }
976e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    if (!success) {
977e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        return NO_MEMORY;
978e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    }
979e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    hidlMem = mapMemory(hidlMemToken);
980e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    if (hidlMem == nullptr) {
981e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        return NO_MEMORY;
982e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    }
983e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    err = mOMXNode->useBuffer(
984e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                            portIndex, hidlMemToken, &info.mBufferID);
985e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa
986e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    if (mode == IOMX::kPortModeDynamicANWBuffer) {
987e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        VideoNativeMetadata* metaData = (VideoNativeMetadata*)(
988e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                (void*)hidlMem->getPointer());
989e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        metaData->nFenceFd = -1;
990e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    }
991e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa
992e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    info.mCodecData = new SharedMemoryBuffer(
993e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                            format, hidlMem);
994e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    info.mCodecRef = hidlMem;
995e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa
996e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    // if we require conversion, allocate conversion buffer for client use;
997e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    // otherwise, reuse codec buffer
998e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    if (mConverter[portIndex] != NULL) {
999e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        CHECK_GT(conversionBufferSize, (size_t)0);
10008a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        bool success;
1001e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        mAllocator[portIndex]->allocate(
1002e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                                conversionBufferSize,
10038a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                [&success, &hidlMemToken](
10048a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                        bool s,
10058a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                        hidl_memory const& m) {
10068a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    success = s;
10078a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                    hidlMemToken = m;
10088a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                                });
10098a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        if (!success) {
10108a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                            return NO_MEMORY;
10118a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        }
10128a21c0191f974a0b9cbd5818052e2655e0aaa306Pawin Vongmasa                        hidlMem = mapMemory(hidlMemToken);
1013f851e5a9f968c519f659bf85e3bd7127dc2a2885Pawin Vongmasa                        if (hidlMem == nullptr) {
1014f851e5a9f968c519f659bf85e3bd7127dc2a2885Pawin Vongmasa                            return NO_MEMORY;
1015f851e5a9f968c519f659bf85e3bd7127dc2a2885Pawin Vongmasa                        }
1016e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        info.mData = new SharedMemoryBuffer(format, hidlMem);
1017e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                        info.mMemRef = hidlMem;
10185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else {
10195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = info.mCodecData;
10205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = info.mCodecRef;
10215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
10231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
10251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
10261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1033dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    std::vector<ACodecBufferChannel::BufferAndId> array(mBuffers[portIndex].size());
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1035dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        array[i] = {mBuffers[portIndex][i].mData, mBuffers[portIndex][i].mBufferID};
1036dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
1037dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (portIndex == kPortIndexInput) {
10384a9ab2a382558941ea7fe92324a3d97848686ca8Dongwon Kang        mBufferChannel->setInputBufferArray(array);
1039dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    } else if (portIndex == kPortIndexOutput) {
1040dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->setOutputBufferArray(array);
1041dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    } else {
1042dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        TRESPASS();
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1048e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
1049098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
1050098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        bool reconnect) {
10511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
10521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
10531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
10541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1055d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
1056d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
10571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
10591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
10601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10626f0789a0ba1656215feb71470db47c6325bd7d87David Yeh    OMX_INDEXTYPE index;
10636f0789a0ba1656215feb71470db47c6325bd7d87David Yeh    err = mOMXNode->getExtensionIndex(
10646f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            "OMX.google.android.index.AndroidNativeBufferConsumerUsage",
10656f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            &index);
10666f0789a0ba1656215feb71470db47c6325bd7d87David Yeh
10676f0789a0ba1656215feb71470db47c6325bd7d87David Yeh    if (err != OK) {
10686f0789a0ba1656215feb71470db47c6325bd7d87David Yeh        // allow failure
10696f0789a0ba1656215feb71470db47c6325bd7d87David Yeh        err = OK;
10706f0789a0ba1656215feb71470db47c6325bd7d87David Yeh    } else {
10716f0789a0ba1656215feb71470db47c6325bd7d87David Yeh        int usageBits = 0;
10726f0789a0ba1656215feb71470db47c6325bd7d87David Yeh        if (nativeWindow->query(
10736f0789a0ba1656215feb71470db47c6325bd7d87David Yeh                nativeWindow,
10746f0789a0ba1656215feb71470db47c6325bd7d87David Yeh                NATIVE_WINDOW_CONSUMER_USAGE_BITS,
10756f0789a0ba1656215feb71470db47c6325bd7d87David Yeh                &usageBits) == OK) {
10766f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            OMX_PARAM_U32TYPE params;
10776f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            InitOMXParams(&params);
10786f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            params.nPortIndex = kPortIndexOutput;
10796f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            params.nU32 = (OMX_U32)usageBits;
10806f0789a0ba1656215feb71470db47c6325bd7d87David Yeh
10816f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            err = mOMXNode->setParameter(index, &params, sizeof(params));
10826f0789a0ba1656215feb71470db47c6325bd7d87David Yeh
10836f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            if (err != OK) {
10846f0789a0ba1656215feb71470db47c6325bd7d87David Yeh                ALOGE("Fail to set AndroidNativeBufferConsumerUsage: %d", err);
10856f0789a0ba1656215feb71470db47c6325bd7d87David Yeh                return err;
10866f0789a0ba1656215feb71470db47c6325bd7d87David Yeh            }
10876f0789a0ba1656215feb71470db47c6325bd7d87David Yeh        }
10886f0789a0ba1656215feb71470db47c6325bd7d87David Yeh    }
10896f0789a0ba1656215feb71470db47c6325bd7d87David Yeh
10901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
1091d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
10921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
10931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
10941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
10951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
10961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
10981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
11001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
11011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
11021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1103f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
1104e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
1105b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
1106fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
1107fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
1108fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
11091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
1110607e65286b7c3dcd06b7175c9d81b82e6fcfcb9aWonsik Kim    return setNativeWindowSizeFormatAndUsage(
11111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
11121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
11131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
11141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
11151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
1116098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            usage,
1117098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            reconnect);
11181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
11191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
11201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
11211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
1122098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        OMX_U32 *minUndequeuedBuffers, bool preregister) {
1123098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar
11241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
11251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
11261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
11271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1128d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
1129d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
11301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
11311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
1132098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        err = setupNativeWindowSizeFormatAndUsage(
1133903896b72e3810e77166f7570e2d5a420241238aLajos Molnar                mNativeWindow.get(), &mNativeWindowUsageBits,
1134903896b72e3810e77166f7570e2d5a420241238aLajos Molnar                preregister && !mTunneled /* reconnect */);
11351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
11361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
1137e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
11381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
11391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
11401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1141ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
1142ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
1143ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
1144ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1145ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1146ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
1147d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1148d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1149ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1150ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
1151ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
1152ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
1153ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
1154ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1155ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1156054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
1157258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
1158258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1159054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
1160258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1161258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
116229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1163258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
1164258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
1165258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1166258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1167e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
1168e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
11691faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
11701faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1171e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1172e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
1173e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
1174e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1175e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
1176e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
1177e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
11781faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
11791faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1180e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
1181e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1182258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1183d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1184d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1185258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1186e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1187e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1188e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1189e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1190e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1191609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1192e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1193e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1194e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1195258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1196258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1197258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1198258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
120329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1208054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1209054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1210054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1211054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1212054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1213054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1214d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    // This method only handles the non-metadata mode (or simulating legacy
1215d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    // mode with metadata, which is transparent to ACodec).
1216d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    CHECK(!storingMetadataInDecodedBuffers());
12173fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1218054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1219054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1220098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
1221054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1222054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1223e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1224054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
12253fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    static_cast<Surface*>(mNativeWindow.get())
12263fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            ->getIGraphicBufferProducer()->allowAllocation(true);
12273298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1228609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1233054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
12348ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
123515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
123615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
123829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124204e331c5032609f7ed42c344780b9c1b4cfe4afbMathias Agopian        sp<GraphicBuffer> graphicBuffer(GraphicBuffer::from(buf));
124374006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
124474006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
124515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
124615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
124790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
124874006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
12491b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang        info.mNewGraphicBuffer = false;
12503fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
12513fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode
12523fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        //       OMX doesn't use the shared memory buffer, but some code still
12533fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        //       access info.mData. Create an ABuffer as a placeholder.
1254d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1255d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mCodecData = info.mData;
12563fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
125774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
125874006804065941841883c4b46ee785070164023fJamie Gennis
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
12603fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId);
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1262609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
126374006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
126874006804065941841883c4b46ee785070164023fJamie Gennis
1269609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1277d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK) {
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
12793fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        // that were dequeued. Also cancel all if we're in legacy metadata mode.
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
128174006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1283054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1284054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1285054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
12903175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
12913175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
12923175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
12933175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
12943175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
12953fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12983fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    static_cast<Surface*>(mNativeWindow.get())
12993fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            ->getIGraphicBufferProducer()->allowAllocation(false);
13003fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1304054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1305d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    CHECK(storingMetadataInDecodedBuffers());
13063fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1307054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1308054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1309098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers,
13103fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            false /* preregister */);
1311d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK)
1312054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1313e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1314054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1315e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1316e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1317e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1318e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1319e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1320e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
132115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
132290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1323e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
13241b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang        info.mNewGraphicBuffer = false;
1325e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1326e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1327d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1328349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang
1329349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang        // Initialize fence fd to -1 to avoid warning in freeBuffer().
1330349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang        ((VideoNativeMetadata *)info.mData->base())->nFenceFd = -1;
1331349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang
13325b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
1333e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1334d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID);
1335e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1336e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1337d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        ALOGV("[%s] allocated meta buffer with ID %u",
1338d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                mComponentName.c_str(), info.mBufferID);
1339e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1340e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1341054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1342054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1343054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1344054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1345054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1346054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1347054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1348054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1349054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1350054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
13510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1352054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
13530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1354054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1355609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
13561b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer->handle);
1357054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1358054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
135915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
13603fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    return fillBuffer(info);
1361054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1362054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
136315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
136415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
136515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
136615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
136715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
136815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
136915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
137015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
137115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
137215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
13730806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
13740806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
13750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
13760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
13770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
13780806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
13790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
13800806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
13810806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
13820806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
13830806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13840806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13850806340688c937e7b78c2d89db3809274130df4eLajos Molnar
13860806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
13870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
13880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
13890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
13900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
13910806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
13920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
13930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
13940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
13950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
13960806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
13970806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
13980806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1402609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
140715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
140815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14103fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
14113fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
14120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14153fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
141890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
141990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
142090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
142190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
142290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
142390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
142490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
142590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
142690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
142790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
142890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
142990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
143090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
143190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
143290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
143390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
143490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
143590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
143690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
143790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
143890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
143990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
144090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
144190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1442604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1443604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1444604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1445604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1446604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1447604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
144890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
144990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
145090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
145179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCallback->onOutputFramesRendered(done);
145290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
145390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1454f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
14558ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1456054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1457ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1458ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1459ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1460ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1461ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1462ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1463ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1464346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1465346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1466346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1467346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1468346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
146915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1470dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
147115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
147215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
147315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1474dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1475dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1477dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1478b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1479b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1480dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1481dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1482dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
148390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1484dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1485dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1486dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1487dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1488dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1489dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1490dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1491dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1492dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1493dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1494dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1495dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
149690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
14971b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                ALOGV("dequeued buffer #%u with age %u, graphicBuffer %p",
14981b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                        (unsigned)(info - &mBuffers[kPortIndexOutput][0]),
14991b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                        mDequeueCounter - info->mDequeuedAt,
15001b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang                        info->mGraphicBuffer->handle);
15011b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang
1502dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
150315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
150490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1505dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1506dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1507dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1509dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1510dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1511dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1512dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1513dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1514d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (!stale && !storingMetadataInDecodedBuffers()) {
1515dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1516dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1517dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1518dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1519dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1520dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1522dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1523054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1524dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1525dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1526b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1527b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1528dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1529dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1530054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1531054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1532054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1533054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1534054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1535054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1536054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1537054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1538054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
15390806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
15400806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
15410806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
15420806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1543054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1544054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
15450806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
154604e331c5032609f7ed42c344780b9c1b4cfe4afbMathias Agopian    oldest->mGraphicBuffer = GraphicBuffer::from(buf);
15471b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    oldest->mNewGraphicBuffer = true;
15480806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
154915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
155090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
155190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1552d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1553d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p",
1554d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1555d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mDequeueCounter - oldest->mDequeuedAt,
15561b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang            oldest->mGraphicBuffer->handle);
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
155890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
15590806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1563dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (portIndex == kPortIndexInput) {
1564dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->setInputBufferArray({});
1565dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    } else {
1566dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->setOutputBufferArray({});
1567dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
1568dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
1569777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1570938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1571938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1572777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1573777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1574777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1575777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1578e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa    mAllocator[portIndex].clear();
1579777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1582349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1583777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1584938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1585938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15892ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
15902ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
15912ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
15922ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1593777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1594777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1595777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1596777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1600777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
16050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
160715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
1608d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL
1609fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
1610fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim        int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd;
161115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
161215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
161315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
161415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
161515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
161615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
16170806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
16180806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
16190806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
16200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
16210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
16220806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1625d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
16260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
16270806340688c937e7b78c2d89db3809274130df4eLajos Molnar
16280806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
16290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
16300806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
16310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
163515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
163615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
163715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1638604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1639604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1640604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1641604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
164290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1643d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    // remove buffer even if mOMXNode->freeBuffer fails
1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1645777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1648f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
16490806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1661777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16653fd200feb657c157125e45e30c2a7262e3c0244dChong Zhangstatus_t ACodec::fillBuffer(BufferInfo *info) {
16663fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    status_t err;
16671b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // Even in dynamic ANW buffer mode, if the graphic buffer is not changing,
16681b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // send sPreset instead of the same graphic buffer, so that OMX server
16691b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // side doesn't update the meta. In theory it should make no difference,
16701b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // however when the same buffer is parcelled again, a new handle could be
16711b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // created on server side, and some decoder doesn't recognize the handle
16721b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    // even if it's the same buffer.
16731b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    if (!storingMetadataInDecodedBuffers() || !info->mNewGraphicBuffer) {
16743fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->fillBuffer(
16753fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            info->mBufferID, OMXBuffer::sPreset, info->mFenceFd);
16763fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    } else {
16773fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->fillBuffer(
16783fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            info->mBufferID, info->mGraphicBuffer, info->mFenceFd);
16793fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    }
16803fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
16811b35986c5045a97dbe852ab93046ab29bcb6a2deChong Zhang    info->mNewGraphicBuffer = false;
16823fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    info->mFenceFd = -1;
16833fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    if (err == OK) {
16843fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
16853fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    }
16863fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    return err;
16873fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang}
16883fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
16911ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime);
16925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
16935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
16945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
1695d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = SetComponentRole(mOMXNode, role);
16965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
16975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
16985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
16995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
17005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
17015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
17025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1710b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1711b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1712b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1715456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    mIsVideo = !strncasecmp(mime, "video/", 6);
1716816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    mIsImage = !strncasecmp(mime, "image/", 6);
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1718d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
1719d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
17208db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1727456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    OMX_VIDEO_CONTROLRATETYPE bitrateMode;
1728456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    int32_t bitrate = 0, quality;
1729456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    // FLAC encoder or video encoder in constant quality mode doesn't need a
1730456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    // bitrate, other encoders do.
1731456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    if (encoder) {
1732816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        if (mIsVideo || mIsImage) {
1733816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            if (!findVideoBitrateControlInfo(msg, &bitrateMode, &bitrate, &quality)) {
1734816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang                return INVALID_OPERATION;
1735816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            }
1736816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
1737456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            && !msg->findInt32("bitrate", &bitrate)) {
1738456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            return INVALID_OPERATION;
1739456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        }
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
174296bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    // propagate bitrate to the output so that the muxer has it
1743456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    if (encoder && msg->findInt32("bitrate", &bitrate)) {
174496bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
174596bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
1746456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        outputFormat->setInt32("bitrate", bitrate);
1747456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        outputFormat->setInt32("max-bitrate", bitrate);
174896bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    }
174996bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar
1750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
17523e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
17533e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && storeMeta != kMetadataBufferTypeInvalid) {
1754d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        IOMX::PortMode mode;
1755d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
1756d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mode = IOMX::kPortModeDynamicNativeHandle;
1757d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
1758d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                storeMeta == kMetadataBufferTypeGrallocSource) {
1759d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mode = IOMX::kPortModeDynamicANWBuffer;
1760d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else {
1761d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            return BAD_VALUE;
1762d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        }
1763d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = setPortMode(kPortIndexInput, mode);
1764d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1765054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
1766054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1767c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1768c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1769d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
1770d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1771c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1772c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1773c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1774c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1775054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1776d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1777308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
17783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
17793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
17803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
17813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
1782d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getExtensionIndex(
1783d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
17843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
17863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
17873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
17883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
17893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1790d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(index, &params, sizeof(params));
17913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
17943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
17953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
17963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
17983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
18003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1801308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1802308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1803308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1804456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    if (encoder && mIsVideo) {
1805308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
18063e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
1807308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1808d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (mFlags & kFlagIsSecure) {
1809d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            enable = OMX_TRUE;
1810d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        }
1811308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1812d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = setPortMode(kPortIndexOutput, enable ?
1813d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer);
1814308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1815d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            return err;
1816308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1817a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1818a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1819a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1820a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1821a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1822a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
182394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
18243604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        // only allow 32-bit value, since we pass it as U32 to OMX.
182594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
18266c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang            mMaxPtsGapUs = 0ll;
18276c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang        } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < INT32_MIN) {
18283604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang            ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs);
18296c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang            mMaxPtsGapUs = 0ll;
18302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
18312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
183237b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
183337b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
183437b2b389139ed638831e49708c947863eef631efRonghua Wu        }
183537b2b389139ed638831e49708c947863eef631efRonghua Wu
18366c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang        // notify GraphicBufferSource to allow backward frames
18376c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang        if (mMaxPtsGapUs < 0ll) {
18386c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang            mMaxFps = -1;
18396c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang        }
18406c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang
184122dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        if (!msg->findDouble("time-lapse-fps", &mCaptureFps)) {
184222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa            mCaptureFps = -1.0;
184394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
184472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
184572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
184672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
184772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
184872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
184972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1850308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1851308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
18523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
18540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
1855456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            && obj != NULL && mIsVideo && !encoder;
1856b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1857456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    if (mIsVideo && !encoder) {
1858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
18591713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
18601713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
18611713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
18621713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
18631713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
18641713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
18651713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
18661713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
18671713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
18681713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1869cec27969ca4bdb5be6c7b1c9f40bea01dddb644cWonsik Kim    }
1870cec27969ca4bdb5be6c7b1c9f40bea01dddb644cWonsik Kim    if (mFlags & kFlagIsSecure) {
1871cec27969ca4bdb5be6c7b1c9f40bea01dddb644cWonsik Kim        // use native_handles for secure input buffers
1872cec27969ca4bdb5be6c7b1c9f40bea01dddb644cWonsik Kim        err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer);
1873a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1874cec27969ca4bdb5be6c7b1c9f40bea01dddb644cWonsik Kim        if (err != OK) {
1875cec27969ca4bdb5be6c7b1c9f40bea01dddb644cWonsik Kim            ALOGI("falling back to non-native_handles");
1876cec27969ca4bdb5be6c7b1c9f40bea01dddb644cWonsik Kim            setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
1877cec27969ca4bdb5be6c7b1c9f40bea01dddb644cWonsik Kim            err = OK; // ignore error for now
1878a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1879e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
18803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
18811de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
18821de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
18835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18846597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
18856597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
18866597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
18876597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
18886597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
18896597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
18906597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
1891d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t temp = mOMXNode->setConfig(
1892d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
18936597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
18946597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
18956597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
18966597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
18976597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
18986597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
18996597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
19006597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
19016597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
19025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
19035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
19045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
19055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1906ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
19075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
190897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
190997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
19105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
19115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
19125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
19135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
191497827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
19155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
19165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1917fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1918fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1919d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1920d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1921d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1922d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1923d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mOMXNode->prepareForAdaptivePlayback(
1924d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1925d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1926d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1927d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
19283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
19293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1930d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1931d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1932d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1933d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1934d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1935d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
19365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1937ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1938ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1939ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
19403fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
19413fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
19423fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
19433fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
19443fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
19453fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
19463fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
19473fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
19483fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
1949d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer);
19505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
19515a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
19525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
19535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
19545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
19565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
19575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
19585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
19595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
19605a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
19625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
19635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
19645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
19655a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
19665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
19675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
19685a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
19695a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
19705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
19715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
19725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
19745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
19755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
19765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
19775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
19785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
19795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1980d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->prepareForAdaptivePlayback(
1981d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
19825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
19835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
19845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
19855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
19875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
19885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
19895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
19905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1991e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1992cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang                // allow failure
1993cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang                err = OK;
19945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
1995d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                ALOGV("[%s] setPortMode on output to %s succeeded",
1996d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                        mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer));
1997054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
19985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1999fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
20000167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
20015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
20025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
20035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
20045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
20055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
20060167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
2007e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
2008e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
2009e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
2010e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
2011e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
2012e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
2013e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
2014054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
2015054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
20165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
20175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
20185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
20195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
2020816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    if (mIsVideo || mIsImage) {
20213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
20223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
20233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
20243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
20253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
2026cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            (void)setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
2027cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang        } else if (haveNativeWindow && !storingMetadataInDecodedBuffers()) {
2028cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer);
2029cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            if (err != OK) {
2030cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang                return err;
2031cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            }
20323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
2035b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2037b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
20413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
20423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20443a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
20451de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
20463a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
2047cd43370e46a619014fdf929dab0bbbba3fdf44b4Chong Zhang            // fallback for devices that do not handle flex-YUV for native buffers
20483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
20493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
20503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
2051777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
2052777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
2053777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
2054777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
20553a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
20563a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
2057777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
2058777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
2059777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
2060777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
20613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
20623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
20631ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                if (!IsFlexibleColorFormat(
2064d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
20653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
20663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
20673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
20683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
20693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
2070e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
20713a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
20723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
2073d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    // TODO: implement adaptive-playback support for bytebuffer mode.
2074d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    // This is done by SW codecs, but most HW codecs don't support it.
2075d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
2076d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    inputFormat->setInt32("adaptive-playback", false);
20773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
20783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
20793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
20803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
2081b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
2082b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
20853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
20863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
20893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
20903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
209142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
209242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
209342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
209442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
209542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
209642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
209742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
209842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
209942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
210042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
210142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
210242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
210342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2110aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
2111b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
21128045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
21132965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
21148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
2115ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
2116ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
2117ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
2118aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
2119aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
2120aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
2121b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2122b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
2123b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
2124ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
21258045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
21268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
21278045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21282965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
21292965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
21302965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
21312965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
21328045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
21338045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21348045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
21358045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21368045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
21378045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21388045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
21398045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21408045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
21418045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21428045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
21438045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21448045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
21458045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21468045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
21478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
21488045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
21498045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
21508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
21518045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
2152b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            if (!msg->findInt32("aac-drc-effect-type", &drc.effectType)) {
2153b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi                // value is unknown
2154b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi                drc.effectType = -2; // valid values are -1 and over
2155b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            }
21568045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2157ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
2158456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang                    encoder, numChannels, sampleRate, bitrate, aacProfile,
21592965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
21602965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2162729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
2163456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        err = setupAMRCodec(encoder, false /* isWAMR */, bitrate);
2164729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
2165456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        err = setupAMRCodec(encoder, true /* isWAMR */, bitrate);
2166729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2167729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2168729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2169729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2170729de186450f78c099637e1fce743fe531862c52Andreas Huber
2171729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
217517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
217617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
217717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
217817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
217917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2182ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
21832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
21842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
21852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
21862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
21872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
21882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
21892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2190516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2191cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2192cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2193516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2194cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
21952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2196516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2197516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2198516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
22002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2201516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2202516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2203516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
22042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
22052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
22062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2207516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2208516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
22092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2210ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2211ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2212ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2213ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2214ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2215ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2216ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
22175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2218ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
221997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
222097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
222197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
222297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
222397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
222497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
222597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
222697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
222797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
22288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
22298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
22308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
22318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
22328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
22338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
22348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
22358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
22368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2238729de186450f78c099637e1fce743fe531862c52Andreas Huber
22394471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
22404471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
22414471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
22424471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
22438b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
22448b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
22458b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
22469806555d3930be43e11106281dee354820ac1c88Andreas Huber
22478b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
22488b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
22498b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
22508b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
22519806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
22529806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
22539806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
22549806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
22559806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
22569806555d3930be43e11106281dee354820ac1c88Andreas Huber
2257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
226001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = OK; // ignore error
2261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
226301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = OK; // ignore error
2264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22668b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
22678b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
22688b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
226901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = OK; // ignore error
22708b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22718b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2272ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2273ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2274ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2275ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2276ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2277ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2278ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2279456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        err = setOperatingRate(rateFloat, mIsVideo);
228001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = OK; // ignore errors
228101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
228201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
228301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (err == OK) {
228401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        err = setVendorParameters(msg);
228501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (err != OK) {
228601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return err;
228701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
2288ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2289ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2290697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
22914e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2292b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
22934e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2294777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2295777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2296777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2297777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2298777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2299777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2300777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2301777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
23025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
23035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // create data converters if needed
2304816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    if (!mIsVideo && !mIsImage && err == OK) {
23055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
23065b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (encoder) {
23075b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
23085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
23095b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexInput] != NULL) {
23105b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
23115b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
23125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        } else {
23135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
23145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
23155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexOutput] != NULL) {
23165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
23175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
23185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
23195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
23205b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuangstatus_t ACodec::setLatency(uint32_t latency) {
232589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    OMX_PARAM_U32TYPE config;
232689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    InitOMXParams(&config);
232789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    config.nPortIndex = kPortIndexInput;
232889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    config.nU32 = (OMX_U32)latency;
232989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    status_t err = mOMXNode->setConfig(
233089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            (OMX_INDEXTYPE)OMX_IndexConfigLatency,
233189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            &config, sizeof(config));
233289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    return err;
233389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang}
233489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
233589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuangstatus_t ACodec::getLatency(uint32_t *latency) {
233689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    OMX_PARAM_U32TYPE config;
233789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    InitOMXParams(&config);
233889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    config.nPortIndex = kPortIndexInput;
233989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    status_t err = mOMXNode->getConfig(
234089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            (OMX_INDEXTYPE)OMX_IndexConfigLatency,
234189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            &config, sizeof(config));
234289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    if (err == OK) {
234389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        *latency = config.nU32;
234489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    }
234589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    return err;
234689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang}
234789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
23488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
23498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
23508b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
23518b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
23528b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
23538b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
23548b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
2355d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t temp = mOMXNode->setConfig(
2356d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigPriority,
23578b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
23588b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
23598b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
23608b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
23618b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
23628b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
23638b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2364ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2365ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2366ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2367ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2368ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2369ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2370ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2371ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2372ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2373ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2374ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2375ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2376ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2377ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2378ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2379ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2380ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2381ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2382ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2383d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2384d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2385ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2386ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2387ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2388ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2389ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2390ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2391ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2392870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2393870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2394870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2395870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2396d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getConfig(
2397d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2398870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2399870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2400870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2401870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2402870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2403870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2404870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2405870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2406870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2407870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2408d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2409d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2410870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2411870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2412870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2413870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2414870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2415870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2416870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2417870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2418870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2419870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2420870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2421d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2422d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2423870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2424870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2425870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2426870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2427870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2428870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2429870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2430870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2431870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2432870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2433870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2434870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2435870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2436870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2437870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2438870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2439870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2440d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2441d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2442870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2443870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2444870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2445870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2446870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2447870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2448870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2449870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2450870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2451870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2452870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2453870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2454870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2455870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2456870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2457870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2458870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2459870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2460870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2461870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2462870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2463870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2464870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2465870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2466870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2467870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2468d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2469d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
2470870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2471870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2472870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2473870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2474870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2475870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2476870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2477870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2478870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2479d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2480d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh,
2481d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &refreshParams, sizeof(refreshParams));
2482870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2483870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2484870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2485870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2486870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2487870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2488870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
24890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnarstatus_t ACodec::configureTemporalLayers(
24900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) {
24910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!mIsVideo || !mIsEncoder) {
24920f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return INVALID_OPERATION;
24930f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24940f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
24950f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString tsSchema;
24960f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!msg->findString("ts-schema", &tsSchema)) {
24970f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return OK;
24980f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24990f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25000f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numLayers = 0;
25010f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numBLayers = 0;
25020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    int tags;
25030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    char dummy;
25040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
25050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
25060f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
25070f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0) {
25080f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
25090f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
25100f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                    &numLayers, &dummy, &numBLayers, &dummy))
25110f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && (tags == 1 || (tags == 3 && dummy == '+'))
25120f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
25130f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        numLayers += numBLayers;
25140f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
25150f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
25160f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
25170f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
25180f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25190f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25200f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
25210f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    InitOMXParams(&layerParams);
25220f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    layerParams.nPortIndex = kPortIndexOutput;
25230f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2524d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2525d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2526d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &layerParams, sizeof(layerParams));
25270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
25290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
25300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (!(layerParams.eSupportedPatterns & pattern)) {
25310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
25320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numLayers = min(numLayers, layerParams.nLayerCountMax);
25350f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numBLayers = min(numBLayers, layerParams.nBLayerCountMax);
25360f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25370f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!inConfigure) {
25380f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
25390f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        InitOMXParams(&layerConfig);
25400f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPortIndex = kPortIndexOutput;
25410f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.ePattern = pattern;
25420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPLayerCountActual = numLayers - numBLayers;
25430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nBLayerCountActual = numBLayers;
25440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
25450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2546d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(
2547d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
25480f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerConfig, sizeof(layerConfig));
25490f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
25500f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.ePattern = pattern;
25510f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nPLayerCountActual = numLayers - numBLayers;
25520f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nBLayerCountActual = numBLayers;
25530f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.bBitrateRatiosSpecified = OMX_FALSE;
25540f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2555d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2556d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
25570f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerParams, sizeof(layerParams));
25580f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25590f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25600f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString configSchema;
25610f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) {
25620f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers);
25630f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
25640f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("webrtc.vp8.%u", numLayers);
25650f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25660f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25670f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
25680f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGW("Failed to set temporal layers to %s (requested %s)",
25690f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                configSchema.c_str(), tsSchema.c_str());
25700f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
25710f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25720f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2573d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2574d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
25750f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            &layerParams, sizeof(layerParams));
25760f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25770f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err == OK) {
25780f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)",
25790f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                tsSchema.c_str(), configSchema.c_str(),
25800f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                asString(layerParams.ePattern), layerParams.ePattern,
25810f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                layerParams.nPLayerCountActual, layerParams.nBLayerCountActual);
25820f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
25830f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        if (outputFormat.get() == mOutputFormat.get()) {
25840f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            mOutputFormat = mOutputFormat->dup(); // trigger an output format change event
25850f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        }
25860f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        // assume we got what we configured
25870f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        outputFormat->setString("ts-schema", configSchema);
25880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
25890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    return err;
25900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar}
25910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2597d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2598d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2610d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2611d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2617d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2618d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2624777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2625777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2626777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2627777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
26386e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
2640d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2641d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPortFormat, &format, sizeof(format));
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
26485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
26516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
26526e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
26536e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
26546e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
26556e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
26566e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2659d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2660d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPortFormat, &format, sizeof(format));
26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2664aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
26658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
26662965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
26672965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2668ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2669ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2670ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2671ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2692d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2693d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2702d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2703d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2713d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2714d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2732aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2734b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2735b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2736b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2737b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2738b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2739b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2740b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2741b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2742b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2743b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2744b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2745b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2746b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2747b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2748b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2749b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2750b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2751b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2752b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2753b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2754b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2755b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2756b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2757b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2758b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2759b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
27605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2761d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2762d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
27635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2775d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2776d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
2777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2784ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2785ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2786ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2787ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2788ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2790b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE presentation;
2791dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
27928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
27938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
27948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
27958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
27968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
27978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
27982965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
2799b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi    presentation.nDrcEffectType = drc.effectType;
28008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2801d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t res = mOMXNode->setParameter(
2802d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
28038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
28048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
2805b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi        if (mOMXNode->setParameter(
2806b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi                (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
2807b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi                &presentation, sizeof(presentation)) == ERROR_UNSUPPORTED) {
2808b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            // prior to 9.0 we used a different config structure and index
2809b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation8;
2810b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            InitOMXParams(&presentation8);
2811b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            presentation8.nMaxOutputChannels = presentation.nMaxOutputChannels;
2812b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            presentation8.nDrcCut = presentation.nDrcCut;
2813b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            presentation8.nDrcBoost = presentation.nDrcBoost;
2814b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            presentation8.nHeavyCompression = presentation.nHeavyCompression;
2815b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            presentation8.nTargetReferenceLevel = presentation.nTargetReferenceLevel;
2816b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            presentation8.nEncodedTargetLevel = presentation.nEncodedTargetLevel;
2817b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            presentation8.nPCMLimiterEnable = presentation.nPCMLimiterEnable;
2818b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi            (void)mOMXNode->setParameter(
2819d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
2820b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi                &presentation8, sizeof(presentation8));
2821b5d268eb3a68147bc562ddb74e471dbd345c5830Jean-Michel Trivi        }
28228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
28238045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
28248045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
2825b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    mSampleRate = sampleRate;
28268045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
283097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
283197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
283297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
283397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
283497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
283597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
283697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
283797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
283897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
283997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
284097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
284197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
284297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
284397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
284497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
284597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
284697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2847d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2848d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
284997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
285097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
285197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
285297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
285397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
285497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
285597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
285697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2857d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2858d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
285997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
286097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
28618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
28628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
28638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
28648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
28658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
28678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
28688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
28698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
28718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
28728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
28738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
28748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
28768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
28778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
28788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2879d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2880d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
28818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
28838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
28848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
28858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
28878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
28888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2889d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2890d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
28918a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
28928a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2939729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2940729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2942729de186450f78c099637e1fce743fe531862c52Andreas Huber
2943d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2944d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2945729de186450f78c099637e1fce743fe531862c52Andreas Huber
2946729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2947729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2948729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2949729de186450f78c099637e1fce743fe531862c52Andreas Huber
2950729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2953d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2954d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2955729de186450f78c099637e1fce743fe531862c52Andreas Huber
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2959729de186450f78c099637e1fce743fe531862c52Andreas Huber
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
29635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2964729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2965729de186450f78c099637e1fce743fe531862c52Andreas Huber
296617c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2967777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2968777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2969777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2971729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
297217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2973729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2974729de186450f78c099637e1fce743fe531862c52Andreas Huber
29752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
29762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
29772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
29782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
29792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
29802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
29812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
29822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
29832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
2984d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
29852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
29862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
29872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
29882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
29892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
2990d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
29912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
29922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
29932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
29942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
29952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
29962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
29972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
29982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
29992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
30002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
30012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
30022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
3003729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
30045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
3005729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3006729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
3007729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
3008729de186450f78c099637e1fce743fe531862c52Andreas Huber
3009d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
3010d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
3011729de186450f78c099637e1fce743fe531862c52Andreas Huber
3012729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
3013729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
3014729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
3015729de186450f78c099637e1fce743fe531862c52Andreas Huber
3016729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
3017729de186450f78c099637e1fce743fe531862c52Andreas Huber
3018d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3019d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
3020729de186450f78c099637e1fce743fe531862c52Andreas Huber
3021729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
3022729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
3023729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
3024729de186450f78c099637e1fce743fe531862c52Andreas Huber
3025729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
3026729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
3027729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
3028729de186450f78c099637e1fce743fe531862c52Andreas Huber
3029d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3030d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
3031729de186450f78c099637e1fce743fe531862c52Andreas Huber
3032729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
3033729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
3034729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
3035729de186450f78c099637e1fce743fe531862c52Andreas Huber
3036729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
30375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    switch (encoding) {
30385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm8bit:
30395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataUnsigned;
30405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 8;
30415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
30425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcmFloat:
30435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataFloat;
30445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 32;
30455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
30465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm16bit:
30475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataSigned;
30485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 16;
30495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
30505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        default:
30515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            return BAD_VALUE;
30525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
3053729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
3054729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
3055729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
3056729de186450f78c099637e1fce743fe531862c52Andreas Huber
3057c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
3058c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
3059729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
3060729de186450f78c099637e1fce743fe531862c52Andreas Huber
3061d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3062d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
30635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // if we could not set up raw format to non-16-bit, try with 16-bit
30645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // NOTE: we will also verify this via readback, in case codec ignores these fields
30655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (err != OK && encoding != kAudioEncodingPcm16bit) {
30665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.eNumData = OMX_NumericalDataSigned;
30675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.nBitPerSample = 16;
3068d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
3069d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
30705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
30715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return err;
3072729de186450f78c099637e1fce743fe531862c52Andreas Huber}
3073729de186450f78c099637e1fce743fe531862c52Andreas Huber
30745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
307597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
30765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
30775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
3078d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->configureVideoTunnelMode(
3079d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
30805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
30815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
30825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
30835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
30845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
30855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
30865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
30875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
30885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
30895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
30905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
30915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
30925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
30935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
30945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
30980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
30990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31066e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
3108d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3109d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat,
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3116229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
3117229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
31180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
31191ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
3120d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
31210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
3122229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
3123229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
3124229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
3125229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3126229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
31526e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
31536e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
31546e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
31556e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
31566e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3163d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
3164d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
31700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
31710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
31720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
31730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
31740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
31750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
31760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
31770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
31780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
31790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
31800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
31810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
31820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
31830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
31840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
31890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
31900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
31930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
3194d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3195d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat, &format, sizeof(format));
31960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
31970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
31980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
31990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
32000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
32010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
32020d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
32030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
32040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
32050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
32060d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
32070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
32080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
32090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
32100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
32110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
32120d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
32130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
32140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
32150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
32160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
32170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
32180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
32190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
32200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
32211ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
3222d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
32230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
32240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
32250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
32260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
32270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
3228d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
3229d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3232e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
3233e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
3234e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3235e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
3236e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
32372472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3238e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3239e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3240e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
324194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
324294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3243a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3244816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    { MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC, OMX_VIDEO_CodingImageHEIC },
3245e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
3246e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
32475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
32485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3249e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3250e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3251e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3252e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3253e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3254e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3255e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3258e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3259e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3260e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3261e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3262e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3263e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3264e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3265e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3266e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3267e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3268e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3269e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3270e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3271e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3272e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3273e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3274e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3275e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3276e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
32775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3279a6bfb5060824f01041f956c733fec141504c280bHangyu Kuangstatus_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) {
3280a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
3281a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    InitOMXParams(&def);
3282a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nPortIndex = portIndex;
3283a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    status_t err;
3284a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
3285a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3286d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3287d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3288a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3289a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        return err;
3290a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3291a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nBufferCountActual = bufferNum;
3292d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3293d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3294a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3295a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        // Component could reject this request.
3296a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
3297a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3298a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3299a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    return OK;
3300a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang}
3301a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
33025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
33038338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3304b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
330589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
330689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
330789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
330889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
330989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
331089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
33115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
33125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
33135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
33165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3318deb14ec33bc481809b465959882736e2262b667aChong Zhang    if (compressionFormat == OMX_VIDEO_CodingHEVC) {
3319deb14ec33bc481809b465959882736e2262b667aChong Zhang        int32_t profile;
3320deb14ec33bc481809b465959882736e2262b667aChong Zhang        if (msg->findInt32("profile", &profile)) {
3321deb14ec33bc481809b465959882736e2262b667aChong Zhang            // verify if Main10 profile is supported at all, and fail
3322deb14ec33bc481809b465959882736e2262b667aChong Zhang            // immediately if it's not supported.
3323deb14ec33bc481809b465959882736e2262b667aChong Zhang            if (profile == OMX_VIDEO_HEVCProfileMain10 ||
3324deb14ec33bc481809b465959882736e2262b667aChong Zhang                profile == OMX_VIDEO_HEVCProfileMain10HDR10) {
3325deb14ec33bc481809b465959882736e2262b667aChong Zhang                err = verifySupportForProfileAndLevel(
3326deb14ec33bc481809b465959882736e2262b667aChong Zhang                        kPortIndexInput, profile, 0);
3327deb14ec33bc481809b465959882736e2262b667aChong Zhang                if (err != OK) {
3328deb14ec33bc481809b465959882736e2262b667aChong Zhang                    return err;
3329deb14ec33bc481809b465959882736e2262b667aChong Zhang                }
3330deb14ec33bc481809b465959882736e2262b667aChong Zhang            }
3331deb14ec33bc481809b465959882736e2262b667aChong Zhang        }
3332deb14ec33bc481809b465959882736e2262b667aChong Zhang    }
3333deb14ec33bc481809b465959882736e2262b667aChong Zhang
3334f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    if (compressionFormat == OMX_VIDEO_CodingVP9) {
3335f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3336f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        InitOMXParams(&params);
3337f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nPortIndex = kPortIndexInput;
3338f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        // Check if VP9 decoder advertises supported profiles.
3339f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nProfileIndex = 0;
3340d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3341f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                OMX_IndexParamVideoProfileLevelQuerySupported,
3342d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
3343f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        mIsLegacyVP9Decoder = err != OK;
3344f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    }
3345f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang
33465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
335489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
335589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
335689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
335789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
33580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
335989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
336089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
336189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
33620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
336389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
336489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
33650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
336689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3372a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component input buffer number to be |tmp|. If succeed,
3373a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set input port buffer number to be |tmp|. If fail,
3374a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3375a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-input-buffers", &tmp)) {
3376a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexInput, tmp);
3377a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3378a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3379a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3380a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
3381a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component output buffer number to be |tmp|. If succeed,
3382a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set output port buffer number to be |tmp|. If fail,
3383a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3384a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-output-buffers", &tmp)) {
3385a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexOutput, tmp);
3386a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3387a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3388a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3389a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
339078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
339178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
339278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
339378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
339478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
339578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
339678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
339778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
339878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
340078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3414b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3415b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
34168338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
34178338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3418db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3419db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3420db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return err;
3421db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3422db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
34235e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
3424db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
3425db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        err = OK;
3426db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3427b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3431d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3432d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3434b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3435b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3436b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3437b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
34388338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3439b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3440b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3441b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3442d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3443b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3444b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3445b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3446b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3447b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3448b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3449b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3450b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3451b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3452b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3453b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3454b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3455b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3456b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3457db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting color aspects failed even though codec advertises support",
3458b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
34598338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
34608338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
34618338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3462b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3463b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3464b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
34658338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
34668338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3467b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
34688338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3469b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3470b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3471b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3472b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3473b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3474b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3475b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
34768338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34778338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3478b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
34798338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3480b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3481b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3482b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3483b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3484b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3485b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3486b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3487d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
34888338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3489b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3490b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3491b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3492b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3493b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3494b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3495b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3496b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3497b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3498b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3499b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3500b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3501b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3502b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3503b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3504b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3505b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
35068338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3507b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3508b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3509b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
35158338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3525b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
35358338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3536b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3545b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3546b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3549b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3550b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3552b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3553b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3554b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3555b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3556b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
35628338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3563b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
35648338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3565b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3566b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3567b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3568b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3569b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3570b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3571b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3572b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
35738338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
35748338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
35768338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
35778338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3578b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3579b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3580b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3581b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3582b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3583b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3584b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3585b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3586b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3587b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3588b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3589b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3590b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3591b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3592b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3593b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3594b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3595b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3596b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3597b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3598b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3599b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3600b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3601b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3602b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3603b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3604b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3605b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
36068338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
36078338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3608b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3609b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3610b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3613b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3614b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3615b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3616b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3617b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3618b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3619b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3621b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3622b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
36235e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::setHDRStaticInfoForVideoCodec(
36245e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
36255e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
36265e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
36275e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    DescribeHDRStaticInfoParams params;
36285e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    InitOMXParams(&params);
36295e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
36305e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
36315e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    HDRStaticInfo *info = &params.sInfo;
36325e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (getHDRStaticInfoFromFormat(configFormat, info)) {
36335e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
36345e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
36355e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
36365e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    (void)initDescribeHDRStaticInfoIndex();
36375e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
36385e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    // communicate HDR static Info to codec
36395e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    return setHDRStaticInfo(params);
36405e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang}
36415e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
3642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3643b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3644b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
36458338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
36468338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3647b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
36488338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
36498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3650b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3651b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3652b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3653b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3654b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
36558338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3656b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3657b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
36588338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3659b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3660b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3661b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3662b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3663b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3664b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3665b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3666b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3667b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3668b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
36698338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
36708338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3671b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3672b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3673b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3674b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3675b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3676b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
36778338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3678b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3679b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3680b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3681b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3682b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3683b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3684b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3685b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
36868338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3687b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3688b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3689b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3690b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3691b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36945e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
36955e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3696db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    DescribeHDRStaticInfoParams params;
3697db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    InitOMXParams(&params);
36985e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
3699db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3700db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = getHDRStaticInfo(params);
3701db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == OK) {
3702db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        // we only set decodec output HDRStaticInfo if codec supports them
3703db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, format);
3704db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3705db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3706db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3707db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3708db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::initDescribeHDRStaticInfoIndex() {
3709d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3710d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
3711db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3712db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
3713db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3714db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3715db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3716db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3717db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
3718db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3719db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3720d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3721db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3722db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3723db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    const HDRStaticInfo *info = &params.sInfo;
3724db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
3725db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
3726db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str(),
3727db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
3728db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
3729db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
3730db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
3731db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3732db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3733db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting HDRStaticInfo failed even though codec advertises support",
3734db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3735db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3736db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3737db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3738db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
3739db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3740db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3741d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3742db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3743db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3744db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3745db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] getting HDRStaticInfo failed even though codec advertises support",
3746db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3747db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3748db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3749db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
37508338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3751b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3752b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
37535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
37545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
37555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
37595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
37665778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
37675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
37775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3780d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3781d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3787456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    OMX_VIDEO_CONTROLRATETYPE bitrateMode;
3788456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    int32_t width, height, bitrate = 0, quality;
37895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
37905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
3791456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang            || !findVideoBitrateControlInfo(
3792456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang                    msg, &bitrateMode, &bitrate, &quality)) {
37935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
37945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
37975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
37985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
38005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
38075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
38125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
38145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
381522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    float framerate;
381622dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    if (!msg->findFloat("frame-rate", &framerate)) {
38175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
38185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
38195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
382122dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mFps = (double)tmp;
382222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    } else {
382322dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa        mFps = (double)framerate;
38245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
382546de4162827b749866277e1b0519c9beaca60934Hangyu Kuang    // propagate framerate to the output so that the muxer has it
382646de4162827b749866277e1b0519c9beaca60934Hangyu Kuang    outputFormat->setInt32("frame-rate", (int32_t)mFps);
38275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
382822dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    video_def->xFramerate = (OMX_U32)(mFps * 65536);
38295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3830a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3831a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3832a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3833a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3834a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3836d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3837d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
38385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
38415778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
38425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
38475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
38495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
38505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
38665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3867d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3868d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
38695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
38755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
38765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
38775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
38785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
38795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3881d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3882d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
38835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
38865778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3891870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3892870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3893870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3894870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3895870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3896870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3897870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3898870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3899870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3900870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3901870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
390289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    configureEncoderLatency(msg);
390389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
39075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
39085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
39105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
39115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
39125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
39145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
39155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
39165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3917c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3918816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        case OMX_VIDEO_CodingImageHEIC:
3919816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            err = setupHEVCEncoderParameters(msg, outputFormat);
3920c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3921c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
392289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
392389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
39249bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            err = setupVPXEncoderParameters(msg, outputFormat);
392589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
392689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
39275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
39285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
39295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
39320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
39330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
39340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
39358338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
39368338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3937b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3938b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
39398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
39408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
39418338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
39428338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
39435e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err != OK) {
39445e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        return err;
39455e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
39465e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
39475e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
39485e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
39495e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
39505e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        err = OK;
39515e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
39525e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
39530f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
39540f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
39550f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
39560f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
39570f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    switch (compressionFormat) {
39580f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingAVC:
39590f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingHEVC:
39600f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat);
39610f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            if (err != OK) {
39620f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                err = OK; // ignore failure
39630f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            }
39640f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
39650f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
39660f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP8:
39670f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP9:
39680f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // TODO: do we need to support android.generic layering? webrtc layering is
39690f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // already set up in setupVPXEncoderParameters.
39700f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
39710f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
39720f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        default:
39730f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
39740f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
39750f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
3976d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3977d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3978d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
39795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
39815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
39840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
39850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
39860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
39870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
39890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
39910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
39920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
39930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
39940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
39950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
39960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
39970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
39980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
39990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
40000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
40010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
40020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
40030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
40040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
40050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
40060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
40070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
40080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
40090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
40100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
40110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
40120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
40130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
4014d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
4015d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
40160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
40170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
40180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
4019f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnarstatic OMX_U32 setPFramesSpacing(
402063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar        float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) {
4021f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // BFramesSpacing is the number of B frames between I/P frames
4022f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // PFramesSpacing (the value to be returned) is the number of P frames between I frames
4023f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
4024f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1
4025f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                                     ^^^                            ^^^        ^^^
4026f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                              number of B frames                number of P    I frame
4027f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
4028f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                  = (PFramesSpacing + 1) * (BFramesSpacing + 1)
4029f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
4030f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // E.g.
4031f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //      I   P   I  : I-interval: 8, nPFrames 1, nBFrames 3
4032f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //       BBB BBB
4033f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
4034f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    if (iFramesInterval < 0) { // just 1 key frame
4035f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1
4036f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    } else if (iFramesInterval == 0) { // just key frames
40375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
40385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4039f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
4040f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // round down as key-frame-interval is an upper limit
4041f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval);
4042f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1);
4043f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    return ret > 0 ? ret - 1 : 0;
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
404763a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
404863a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
40495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
405063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
40515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
40525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4054456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
405596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
40565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
40575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
40585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
40595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
40605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
40615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
40635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
40665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
40675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
40685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4069d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4070d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
40715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
40775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
40785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
40795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
40815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
40825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4083f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nBFrames = 0;
4084f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames);
40855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
40865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
40875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
40895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
40905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
40915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
40925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
40935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
40945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
40965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
40975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
40985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
40995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
41005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4102deb14ec33bc481809b465959882736e2262b667aChong Zhang        err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
41035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
41055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
41065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
41095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
41105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4112d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4113d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
41145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4119456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    err = configureBitrate(bitrateMode, bitrate);
41205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
412963a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
413063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
41315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
413263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
41335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
41345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4136456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
413796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
41385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
41395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
41405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
41415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
41425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
41435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
41455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
41505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4151d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4152d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
41605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4161f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nBFrames = 0;
4162f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames);
41635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
41655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
41685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
41695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
41705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
41715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
41725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4174deb14ec33bc481809b465959882736e2262b667aChong Zhang        err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
41755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
41775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
41785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
41815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
41825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
41855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
41865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
41875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
41885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4189d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4190d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
41915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4196456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    err = configureBitrate(bitrateMode, bitrate);
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
42005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
42035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
42045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4205a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
4206a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
4207a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
420806e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar        OMX_VIDEO_AVCPROFILEEXTTYPE profile) {
4209a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
421006e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar    switch ((uint32_t)profile) {
4211a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
4212a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
421306e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar        case OMX_VIDEO_AVCProfileConstrainedHigh:
4214a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
4215a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
4216a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
4217a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
4218a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4219a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4220a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
4221a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
4222a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
4223a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
4224a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
4225a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
4226a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4227a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
4228a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
4229a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
4230a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
4231a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
4232a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
4233a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
4234a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
4235a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
4236a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
4237a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
4238a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
4239a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
4240a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
4241a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
4242a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
4243a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
4244a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
4245a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
4246a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
4247a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4248a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
4249a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
4250a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
4251a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
4252a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
4253a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
4254a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4255a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
4256a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
4257a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
42585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
425963a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
426063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
42615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
426263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
42635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
42645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4266456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
426796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
42685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
42695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
42705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
42715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
42725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
42735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
42745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
42755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
42780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
42790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
42800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
42810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
42820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
42830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
42840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
42850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
42860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
42870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
42885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
42895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
42905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
42915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4292d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4293d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
42945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
42965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
42975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
42985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
43005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
43015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
43035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
43045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
43055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
43065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
43075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
43085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4309deb14ec33bc481809b465959882736e2262b667aChong Zhang        err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
43105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
43125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
43135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
43145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
43165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
4317e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else {
43188eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
43194c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#if 0   /* DON'T YET DEFAULT TO HIGHEST PROFILE */
43204c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar        // Use largest supported profile for AVC recording if profile is not specified.
4321826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        for (OMX_VIDEO_AVCPROFILETYPE profile : {
4322826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
4323deb14ec33bc481809b465959882736e2262b667aChong Zhang            if (verifySupportForProfileAndLevel(kPortIndexOutput, profile, 0) == OK) {
4324826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                h264type.eProfile = profile;
4325826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                break;
4326826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            }
4327826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        }
43284c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#endif
43298eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    }
43308eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang
4331e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
4332e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            asString(h264type.eProfile), asString(h264type.eLevel));
4333e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang
43345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
43355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
43365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
43375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
43385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
4339f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
43405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
43415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
43425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
43435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
43445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
43455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
43465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
43475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
43485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
43495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
43505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
4351e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
4352e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
4353e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nSliceHeaderSpacing = 0;
4354e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
4355e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefFrames = 2;
435689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        h264type.nBFrames = mLatency == 0 ? 1 : std::min(1U, mLatency - 1);
43579a5222b056d7aeb07335127cc8431428cfb824f2Lajos Molnar
43589a5222b056d7aeb07335127cc8431428cfb824f2Lajos Molnar        // disable B-frames until MPEG4Writer can guarantee finalizing files with B-frames
43599a5222b056d7aeb07335127cc8431428cfb824f2Lajos Molnar        h264type.nRefFrames = 1;
43609a5222b056d7aeb07335127cc8431428cfb824f2Lajos Molnar        h264type.nBFrames = 0;
43619a5222b056d7aeb07335127cc8431428cfb824f2Lajos Molnar
4362f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4363e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nAllowedPictureTypes =
43649a5222b056d7aeb07335127cc8431428cfb824f2Lajos Molnar            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
4365e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
4366e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
4367e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
4368e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
4369e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bconstIpred = OMX_TRUE;
4370e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
4371e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
4372e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nCabacInitIdc = 1;
43735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
43765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
43775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
43805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
43815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
43825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
43835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
43845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
43855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
43865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4387d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4388d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
43895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
43915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
43925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4394e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering
4395e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering
4396e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // is preferred.
4397e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    AString tsSchema;
4398e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    int32_t preferBFrames = (int32_t)false;
4399e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    if (msg->findString("ts-schema", &tsSchema)
4400e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) {
4401e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
4402e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        InitOMXParams(&layering);
4403e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        layering.nPortIndex = kPortIndexOutput;
4404d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
4405d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
4406e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                        &layering, sizeof(layering)) == OK
4407e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.eSupportedPatterns
4408e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.nBLayerCountMax == 0) {
4409e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nBFrames = 0;
4410e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4411e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
4412e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            ALOGI("disabling B-frames");
4413d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(
4414d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4415e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
4416e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            if (err != OK) {
4417e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                return err;
4418e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            }
4419e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        }
4420e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    }
4421e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
4422456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    return configureBitrate(bitrateMode, bitrate);
44235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4425816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhangstatus_t ACodec::configureImageGrid(
4426816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
442767d5b91f2fa0b106c038e642225e3b538db2be2eChong Zhang    int32_t tileWidth, tileHeight, gridRows, gridCols;
442867d5b91f2fa0b106c038e642225e3b538db2be2eChong Zhang    if (!msg->findInt32("tile-width", &tileWidth) ||
442967d5b91f2fa0b106c038e642225e3b538db2be2eChong Zhang        !msg->findInt32("tile-height", &tileHeight) ||
4430816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        !msg->findInt32("grid-rows", &gridRows) ||
4431816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        !msg->findInt32("grid-cols", &gridCols)) {
4432816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        return OK;
4433816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    }
4434816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4435816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE gridType;
4436816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    InitOMXParams(&gridType);
4437816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    gridType.nPortIndex = kPortIndexOutput;
4438816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    gridType.bEnabled = OMX_TRUE;
443967d5b91f2fa0b106c038e642225e3b538db2be2eChong Zhang    gridType.nTileWidth = tileWidth;
444067d5b91f2fa0b106c038e642225e3b538db2be2eChong Zhang    gridType.nTileHeight = tileHeight;
4441816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    gridType.nGridRows = gridRows;
4442816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    gridType.nGridCols = gridCols;
4443816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4444816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    status_t err = mOMXNode->setParameter(
4445816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid,
4446816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            &gridType, sizeof(gridType));
4447816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4448816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    // for video encoders, grid config is only a hint.
4449816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    if (!mIsImage) {
4450816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        return OK;
4451c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4452c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4453816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    // image encoders must support grid config.
4454816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    if (err != OK) {
4455816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        return err;
4456816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    }
4457816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4458816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    // query to get the image encoder's real grid config as it might be
4459816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    // different from the requested, and transfer that to the output.
4460816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    err = mOMXNode->getParameter(
4461816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidImageGrid,
4462816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            &gridType, sizeof(gridType));
4463816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4464816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    if (err == OK && gridType.bEnabled) {
446567d5b91f2fa0b106c038e642225e3b538db2be2eChong Zhang        outputFormat->setInt32("tile-width", gridType.nTileWidth);
446667d5b91f2fa0b106c038e642225e3b538db2be2eChong Zhang        outputFormat->setInt32("tile-height", gridType.nTileHeight);
4467816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        outputFormat->setInt32("grid-rows", gridType.nGridRows);
4468816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        outputFormat->setInt32("grid-cols", gridType.nGridCols);
4469816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    }
4470816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4471816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    return err;
4472816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang}
4473816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4474816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhangstatus_t ACodec::setupHEVCEncoderParameters(
4475816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
4476456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    OMX_VIDEO_CONTROLRATETYPE bitrateMode;
4477456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    int32_t bitrate, quality;
4478456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    if (!findVideoBitrateControlInfo(msg, &bitrateMode, &bitrate, &quality)) {
4479456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        return INVALID_OPERATION;
4480456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    }
4481c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4482c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4483c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4484c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4485c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4486c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4487d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4488d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4489c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4490c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4491c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4492c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4493c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4494c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4495c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4496c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4497c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4498c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4499c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4500deb14ec33bc481809b465959882736e2262b667aChong Zhang        err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
4501c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4502c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4503c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4504c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4505c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4506c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4507c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
45089aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
4509816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    if (mIsImage) {
4510816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        hevcType.nKeyFrameInterval = 1;
4511816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    } else {
4512816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        float iFrameInterval;
4513816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        if (!msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4514816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            return INVALID_OPERATION;
4515816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        }
4516816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4517816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        float frameRate;
4518816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        if (!msg->findFloat("frame-rate", &frameRate)) {
4519816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            int32_t tmp;
4520816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            if (!msg->findInt32("frame-rate", &tmp)) {
4521816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang                return INVALID_OPERATION;
4522816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            }
4523816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang            frameRate = (float)tmp;
4524816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        }
4525816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4526816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        hevcType.nKeyFrameInterval =
4527816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang                setPFramesSpacing(iFrameInterval, frameRate) + 1;
4528816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    }
4529816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4530c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4531d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4532d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4533c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4534c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4535c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4536c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4537816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    err = configureImageGrid(msg, outputFormat);
4538816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4539816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    if (err != OK) {
4540816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang        return err;
4541816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    }
4542816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang
4543456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    return configureBitrate(bitrateMode, bitrate, quality);
4544c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4545c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
45469bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnarstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
454789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
454863a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval = 0;
45494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
45504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
45514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
45524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
45534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
45544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
45554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
45564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
45574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
45584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
455989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
456089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
456189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
456263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    msg->findAsFloat("i-frame-interval", &iFrameInterval);
456389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
4564456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getVideoBitrateMode(msg);
456589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
45664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
45674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
45684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
45694154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
45704154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
45714154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
45724154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
45734154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
45744154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
45754154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
45769bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType =
45779bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
45789bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar
45794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
4580f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numLayers = 0;
4581f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numBLayers = 0;
4582f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        int tags;
4583f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        char dummy;
4584f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
4585f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0) {
45864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
45879bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
4588f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers;
4589f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
4590f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                        &numLayers, &dummy, &numBLayers, &dummy))
4591f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && (tags == 1 || (tags == 3 && dummy == '+'))
4592f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
45934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4594f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            // VPX does not have a concept of B-frames, so just count all layers
45959bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4596f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers + numBLayers;
45974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
4598f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
45994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
4600f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS);
46014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
46024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
46034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
46044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
46054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
4606d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4607d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
46084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
46094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
46104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
46114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
4612f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
46134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
46144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
46154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
46164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
46174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
46184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
46194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
46204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
46214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
46224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
46234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
46244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
46254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
46264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
4627d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
4628d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
46294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
46304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
46314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
46329bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
46339bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // advertise even single layer WebRTC layering, as it is defined
46349bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers));
46359bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsLayers > 0) {
46369bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid
46379bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers));
46384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
46394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
46404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
4641456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    return configureBitrate(bitrateMode, bitrate);
464289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
464389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
46445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
4645deb14ec33bc481809b465959882736e2262b667aChong Zhang        OMX_U32 portIndex, int32_t profile, int32_t level) {
46465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
46475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
4648deb14ec33bc481809b465959882736e2262b667aChong Zhang    params.nPortIndex = portIndex;
46495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
46516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
4652d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
46535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
4654d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
46555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
46575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
46585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
46595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
46615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
46625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
46645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
46655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
46666e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
46676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
46686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
46696e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
46706e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
46716e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
46725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
46736e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
46745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
46755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
467696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
4677456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        OMX_VIDEO_CONTROLRATETYPE bitrateMode, int32_t bitrate, int32_t quality) {
46785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
46795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
46805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
46815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4682d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4683d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
46845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
46865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
46875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
46885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
468996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
4690456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang
4691456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    // write it out explicitly even if it's a union
4692456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    if (bitrateMode == OMX_Video_ControlRateConstantQuality) {
4693456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        bitrateType.nQualityFactor = quality;
4694456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    } else {
4695456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang        bitrateType.nTargetBitrate = bitrate;
4696456dec2be004ef90fb271d413f3bd26b39de0487Chong Zhang    }
46975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4698d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4699d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
47005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
47015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
470289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuangvoid ACodec::configureEncoderLatency(const sp<AMessage> &msg) {
470389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    if (!mIsEncoder || !mIsVideo) {
470489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        return;
470589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    }
470689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
470789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    int32_t latency = 0, bitrateMode;
470889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    if (msg->findInt32("latency", &latency) && latency > 0) {
470989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        status_t err = setLatency(latency);
471089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        if (err != OK) {
471189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            ALOGW("[%s] failed setLatency. Failure is fine since this key is optional",
471289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                    mComponentName.c_str());
471389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            err = OK;
471489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        } else {
471589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            mLatency = latency;
471689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        }
471789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    } else if ((!msg->findInt32("bitrate-mode", &bitrateMode) &&
471889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            bitrateMode == OMX_Video_ControlRateConstant)) {
471989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        // default the latency to be 1 if latency key is not specified or unsupported and bitrateMode
472089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        // is CBR.
472189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        mLatency = 1;
472289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    }
472389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang}
472489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
47255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
47265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
47275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
47285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
47295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4730d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4731d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
47325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
47335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
47355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
47365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
47375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
47395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
47405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
47415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
47425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
47435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4744d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4745d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
47465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
47475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
47485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
475178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
475278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4759d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4760d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4761777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4762777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4763777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4773777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4774777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4775777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4776777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
478478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
478578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
478678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4789d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4790d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4795d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4796d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4797d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4798d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4799d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4800d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4801d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4802d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4803d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4804d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4805d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4806d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4807d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4808d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
48097e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
48107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
48117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
48127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
48137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
48147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
48157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
48167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
48177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
48187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
48197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
48207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
48217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
48227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
48237e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
48247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
48257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
48267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
48277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4828e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
48297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4830c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4831054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4832054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4833c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
48347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
48357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
48367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4844609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4873e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4874777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
487531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
487631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
487831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4879d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
4880777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4881777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4882777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
488331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4884777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4885777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4886777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4887777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
488831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
488931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
489031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
489131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
489231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4893e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4894e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4895e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4896e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4897e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4898e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4899e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4900e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4901e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4902e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
49030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
490473dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
49050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
49060d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
49070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
49080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
49090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
49100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
49110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
49120d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
4913d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (DescribeColorFormat(mOMXNode, describeParams)) {
49140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
49150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
49160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
49170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
49180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
49195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
492073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
492173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
492273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
492373dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
492473dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
492573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
492673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
49270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
492803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
492903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4930b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4931b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4932b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4933b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4934b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4935b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4936b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4937b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4938d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (mOMXNode->getConfig(
4939b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4940b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4941b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4942b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4943b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4944b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4945b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4946b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4947b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
494891a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4949deb14ec33bc481809b465959882736e2262b667aChong Zhang                        if (rect.nLeft < 0 || rect.nTop < 0 ||
4950deb14ec33bc481809b465959882736e2262b667aChong Zhang                            rect.nWidth == 0 || rect.nHeight == 0 ||
4951b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4952b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
495352fda70b8ed8f03cdb63c40c8eff9734b86f4151panshuangquan                            ALOGE("Wrong cropped rect (%d, %d, %u, %u) vs. frame (%u, %u)",
4954b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
495552fda70b8ed8f03cdb63c40c8eff9734b86f4151panshuangquan                                    rect.nWidth, rect.nHeight,
4956b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4957b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4958b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
495931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4960b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4961b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4962b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4963b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4964b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4965b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4966b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4967b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4968b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4969b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4970b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4971b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4972b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4973b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4974b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4975b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4976b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
49775e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
4978b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4979b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
49805e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        if (mConfigFormat->contains("hdr-static-info")) {
49815e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                            (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
49825e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        }
498389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                        uint32_t latency = 0;
4984816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang                        if (mIsEncoder && !mIsImage &&
4985816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang                                getLatency(&latency) == OK && latency > 0) {
498689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                            notify->setInt32("latency", latency);
498789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                        }
4988777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4989e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4990e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4991e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
49924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
49934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
49944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
49954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
49964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
49974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
49984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
4999d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    status_t err = mOMXNode->getParameter(
50004730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
50014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
50024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
50034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
50044730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
50059bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                        if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC
50069bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount > 0
50079bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount
50089bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
50099bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            // advertise as android.generic if we configured for android.generic
50109bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            AString origSchema;
50119bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            if (notify->findString("ts-schema", &origSchema)
50129bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                    && origSchema.startsWith("android.generic")) {
50139bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
50149bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "android.generic.%u", vp8type.nTemporalLayerCount));
50159bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            } else {
50169bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
50179bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount));
50184730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
50194730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
50204730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
50214730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
50224730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
50234730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
5024e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
5025e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
5026777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
5027777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
5028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
5029777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
5030777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
5031777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
5032777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5033e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
5034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
5035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
5036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
5037e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
5038e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
5039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
5040870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
5041816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang                    if (mIsEncoder && !mIsImage &&
5042816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang                            getIntraRefreshPeriod(&intraRefreshPeriod) == OK
5043870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
5044870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
5045870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
5046e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
5047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
504831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
5049e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
5050e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
50515a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
50525a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
50535a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
50545a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
505531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
505631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
505731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
505831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
505931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
506031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
506131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
506297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
5063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
5064e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
5065e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
5066e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
5067e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
5068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5069d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5070d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioPcm, &params, sizeof(params));
5071777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5072777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5073777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
507414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
5075777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
5076777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
5077777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
50785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
5079777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
5080777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
50815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
5082777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
5083777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5084e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5085e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
5086e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
5087e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
50885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
50895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
50905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
50915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
50925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
50935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
50945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
50955b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
50965b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
50975b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
50985b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
50995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
51005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
51015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
51025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
51035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
5104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
5106e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
51078b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
5108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
51098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
51109806555d3930be43e11106281dee354820ac1c88Andreas Huber
5111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
5112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
5113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
5114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
5115e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
5116e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5117d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5118d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAac, &params, sizeof(params));
5119777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5120777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5121777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5122e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5123e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
5124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
5125e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
5126e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
5127e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
5128e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5129e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
5130e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
5131e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
5132e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
5133e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
51349806555d3930be43e11106281dee354820ac1c88Andreas Huber
5135d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5136d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAmr, &params, sizeof(params));
5137777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5138777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5139777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5140e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5141e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
5142e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
51430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
5144e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
5145e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
51460806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
5147e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
5148e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
5149e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
5150e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
5151e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5152e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
5153e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
5154e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
5155e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
5156e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
5157e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5158d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5159d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioFlac, &params, sizeof(params));
5160777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5161777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5162777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5163e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5164e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
5165e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
5166e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
5167e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
5168e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
5169e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
5170e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
5171e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
5172e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
5173e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
5174e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
5175e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5176d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5177d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioMp3, &params, sizeof(params));
5178777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5179777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5180777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5182e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
5183e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
5184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
5185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
5186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
5187e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5188e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
5189e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
5190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
5191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
5192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
5193e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5194d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5195d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioVorbis, &params, sizeof(params));
5196777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5197777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5198777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
5199e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5200e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
5201e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
5202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
5203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
5204e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
5205e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
520697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
520797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
520897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
520997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
5210e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
521197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
5212d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5213d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
5214777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5215777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5216777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5217777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
521897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
521997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
522097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
522197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
522297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
522397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
5224e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
52258a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
52268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
52278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
52288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
52298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
52308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
5231d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5232d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
5233777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5234777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5235777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5236777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
52378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
52388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
52398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
52408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
52418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
52428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
52438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
52448c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
52458c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
52468c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
52478c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
52488c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
52498c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
5250d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5251d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
5252777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
5253777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5254777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5255777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
52568c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
52578c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
52588c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
52598c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
52608c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
52618c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
52628c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
526310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
526410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
526510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
526610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
526710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
526810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
5269d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5270d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
5271777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5272777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5273777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
527410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
527510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
527610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
527710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
527810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
527910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
528010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
528110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
528210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
528310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
528410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
528510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
528678bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
528710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
528810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
528941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
529041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
529141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
52920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
529341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
529441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
529541d3f579d2c166984958263533284209b90c87d5Marco Nelissen
5296d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
5297d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                OMX_IndexParamAudioPcm, &params, sizeof(params));
5298777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
5299777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
5300777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
530141d3f579d2c166984958263533284209b90c87d5Marco Nelissen
530241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
530341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
53040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
530541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
530610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
530710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
5308e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
5309777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
5310777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
5311777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
5312e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
531331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
531431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
531531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
531631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
5317777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
5318777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
531931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
532031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
532101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    return getVendorParameters(portIndex, notify);
5322e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
5323e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5324b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
5325b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
5326b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
5327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
5328b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5329b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
53306f8f2c88c6351218d249c8676ed351fb17c6e17fChong Zhang    if (range == 0) {
5331b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
5332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
53336f8f2c88c6351218d249c8676ed351fb17c6e17fChong Zhang    if (standard == 0) {
5334b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
5335b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
53366f8f2c88c6351218d249c8676ed351fb17c6e17fChong Zhang    if (transfer == 0) {
5337b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
5338b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5339b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5340b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5341b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5342b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
5343b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5345b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
5346b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5347b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5348b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
5349b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5350b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5351b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5352b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5353b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
5354b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
5355b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
5356b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5357b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
5358b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
5359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
5360b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
5361b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
5362b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
53631734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5364697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // store new output format, at the same time mark that this is no longer the first frame
5365b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
5366e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5367b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5368777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5369777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
5370777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5371e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
53721734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    if (expectedFormat != NULL) {
53731734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
53741734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
53751734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        if (changes->countEntries() != 0 || to->countEntries() != 0) {
53761734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
53771734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mComponentName.c_str(),
53781734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    changes->debugString(4).c_str(), to->debugString(4).c_str());
53791734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        }
53801734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    }
53811734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar
53825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
53835b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
53845b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
53855b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
53865b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
53875b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
53885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
53895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
53905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
53915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
53925b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
53935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
5394b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
5395b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
5396b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5397b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5398b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5399b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
5400b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
5401b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5402b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5403b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5404b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        int32_t channelCount, sampleRate;
540584d7e874983ee0d66db328c454fa603374d4635fMarco Nelissen        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5406b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
5407b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        if (mSampleRate != 0 && sampleRate != 0) {
540873e95a9bd43724058651cb11c58dbe3fae651d56Ray Essick            // avoiding 32-bit overflows in intermediate values
540973e95a9bd43724058651cb11c58dbe3fae651d56Ray Essick            mEncoderDelay = (int32_t)((((int64_t)mEncoderDelay) * sampleRate) / mSampleRate);
541073e95a9bd43724058651cb11c58dbe3fae651d56Ray Essick            mEncoderPadding = (int32_t)((((int64_t)mEncoderPadding) * sampleRate) / mSampleRate);
5411b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mSampleRate = sampleRate;
5412b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        }
5413e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
5414e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
5415e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
5416ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5417e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
5418e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
5419b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5420e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
5421e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5422b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5423b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
542431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
542531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
54265778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5427251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5428251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
5429251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
5430251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
5431251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
5432251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
5433251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
5434251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5435251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5436251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5437346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5438346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
543979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCallback->onError(internalError, ACTION_CODE_FATAL);
5440cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5441cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5442496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5443496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5444496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5445496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5446496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5447496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5448496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5449496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5450496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5453d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setConfig(
5454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5457496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5458496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
54597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim////////////////////////////////////////////////////////////////////////////////
54607e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
5461f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5466ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5467ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54714ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kimvoid ACodec::BaseState::stateExited() {
54724ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    ++mCodec->mStateGeneration;
54734ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim}
54744ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
548926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
549026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
549126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
549226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
549326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5494e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5495e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5496e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5497e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5498e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5499e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
550226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
55061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
55071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
55081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
55091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
55101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
55111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
55121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
55132235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
55141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
55151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
55161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
55171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
55181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
55191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
55201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
55217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
55228f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
55237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
55247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5525251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
55267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
55277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
55287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
55297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
55307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5531ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5532ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5533251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5534ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
55356d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            mCodec->mGraphicBufferSource.clear();
5536ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5537ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5538ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5539ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
554030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
554130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
554230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
554330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
5544d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->freeNode();
554530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
554630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
554779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onReleaseCompleted();
5548ec69aafeef06b42d3bfa6c7e4a7fee0cb03d360cWonsik Kim
5549ec69aafeef06b42d3bfa6c7e4a7fee0cb03d360cWonsik Kim            mCodec->changeState(mCodec->mUninitializedState);
555030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
555130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
555230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
55534ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        case ACodec::kWhatForceStateTransition:
55544ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        {
55554ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            ALOGV("Already transitioned --- ignore");
55564ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            break;
55574ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        }
55584ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
55675e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
55685e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5569d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode == NULL) {
55705e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
55715e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
557226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
55735e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
55745e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5575d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    int32_t generation;
5576d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(msg->findInt32("generation", (int32_t*)&generation));
5577d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (generation != mCodec->mNodeGeneration) {
5578d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        ALOGW("Unexpected message for component: %s, gen %u, cur %u",
5579d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
5580777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5581777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
558226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
558326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
558426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
558526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
558626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
558726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
558826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
558926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
559090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
559126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
559226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5593e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5594e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
559590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
559690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
559790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
559890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
559990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
560090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
560190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
560290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
560390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
560490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
560526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
560626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
560726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
560826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
560926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
561026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
561126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56210af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
56220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
56230af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
56240af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
56250af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
56260af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
56270af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
56280af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
56290af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
56300af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
56310af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
564115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
564215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5643609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
564415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
564615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5652609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
565415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
566115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
566715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
566815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
567190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
567290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
567390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
567490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
567590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
567690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
567790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
567890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
567990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
568090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
568190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5683777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5684777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
568990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
569090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
569190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
569290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
569390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5694f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5696b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
56976cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang        ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
5698b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5699b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5700b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5701b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5702b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5704ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5710ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5712251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5713251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5714251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5715251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5716251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5717251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5718251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
572315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5724ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5725349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5726349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
57270806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
57280806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
57290806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
57300806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
57310806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
573215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
573315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
573415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
57350806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
57360806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
574015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
574115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
574215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
574315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
574415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
574515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
574696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
574796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
574896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
574996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
575096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
5751bc8f53b8c1c220d9ce01526b6e3834f14af98ed5Dongwon Kang    info->mData->meta()->setObject("mediaBufferHolder", sp<MediaBufferHolder>(nullptr));
5752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5763777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5765777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5766777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5779ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim    info->mData->setFormat(mCodec->mInputFormat);
5780dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mCodec->mBufferChannel->fillThisBuffer(info->mBufferID);
578179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    info->mData.clear();
5782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5785f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5787609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
57887e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
5789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
57905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5791a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
579276d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    int32_t discarded = 0;
579376d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    if (msg->findInt32("discarded", &discarded) && discarded) {
5794dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        // these are unfilled buffers returned by client
5795dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        // buffers are returned on MediaCodec.flush
5796dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mode = KEEP_BUFFERS;
5797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
579876d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    sp<RefBase> obj;
579976d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    CHECK(msg->findObject("buffer", &obj));
580076d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    buffer = static_cast<MediaCodecBuffer *>(obj.get());
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
58035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
58045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
58055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
58065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
58075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
58090806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
58100806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
58110806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
58120806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
58130806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
58140806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
58150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5818fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    info->mData = buffer;
5819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
58235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5824dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5825dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5826dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5827dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
58345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5835fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5836fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5837fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5838fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5839fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5840fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5846d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                int32_t isCSD = 0;
5847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5848f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    if (mCodec->mIsLegacyVP9Decoder) {
5849f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
5850f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                            mCodec->mComponentName.c_str(), bufferID);
5851f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        postFillThisBuffer(info);
5852f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        break;
5853f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    }
5854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
58585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
58595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
58605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5861fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                size_t size = buffer->size();
586249b2b4d30a0f74314630a5ea5f0e59697d90443eChong Zhang                size_t offset = buffer->offset();
5863fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                if (buffer->base() != info->mCodecData->base()) {
5864ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5865d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5866d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
5867fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                         buffer->base(), info->mCodecData->base());
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
5870d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (converter == NULL || isCSD) {
58715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
58725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
58735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
58745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
58755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
58760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
58770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5878fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                    size = info->mCodecData->size();
58793fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                } else {
588049b2b4d30a0f74314630a5ea5f0e59697d90443eChong Zhang                    info->mCodecData->setRange(offset, size);
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5883078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5884ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5885078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
58865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5887ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
58885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5889078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5890d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5891ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5892ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5893d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5894ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5895ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5896d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5897078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5898349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5899d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5900d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5901d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5902d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5903d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5904d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5905d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5906054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5907054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5908054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5909054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5910054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5911054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5912054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5913054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5914054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5915054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5916054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5917054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
591815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5919d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5920d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                status_t err2 = OK;
5921d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                switch (mCodec->mPortMode[kPortIndexInput]) {
5922d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetByteBuffer:
5923d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetANWBuffer:
5924d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetSecureBuffer:
59253fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    {
59263fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
59273fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
59283fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    }
5929d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5930d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5931d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModeDynamicNativeHandle:
5932d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
5933d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeHandleMetadata *vnhmd =
5934d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            (VideoNativeHandleMetadata*)info->mCodecData->base();
59353fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        sp<NativeHandle> handle = NativeHandle::create(
59363fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                                vnhmd->pHandle, false /* ownsHandle */);
59373fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
59383fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, handle, flags, timeUs, info->mFenceFd);
5939d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5940d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5941d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModeDynamicANWBuffer:
5942d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
5943d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
594404e331c5032609f7ed42c344780b9c1b4cfe4afbMathias Agopian                        sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(vnmd->pBuffer);
59453fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
59463fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, graphicBuffer, flags, timeUs, info->mFenceFd);
5947d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5948d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5949d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#endif
5950d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                default:
5951d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
5952d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                            asString(mCodec->mPortMode[kPortIndexInput]),
5953d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                            info->mCodecData->size(),
5954d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            sizeof(buffer_handle_t) * 8);
5955d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    err2 = ERROR_UNSUPPORTED;
5956d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5957d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
5958d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
595915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
59600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
59610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
59620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
59630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5965fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                // Hold the reference while component is using the buffer.
5966fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                info->mData = buffer;
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
59695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
59705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
59710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
59720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
59735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
59745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
59755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
59765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
59780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
59790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5980dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5981dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
59823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5983dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5984dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5986ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5987349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5988349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
598915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5990d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                status_t err2 = mCodec->mOMXNode->emptyBuffer(
59913fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd);
599215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
59930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
59940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
59950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
59960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
6000dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6004625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
6005777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6006777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
6007777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6008625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
6009777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
6010625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
6011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6014f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
6015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
6025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
6028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
6033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
604715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
604815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
6049609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
60505778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
6051349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
60530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
6054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
6055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
6056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
6057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
6058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
6059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
6060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
6061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
6062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
6063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
6064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
6065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
6066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
6067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
6068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
6069d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
6070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
6071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
60720806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
60730806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
60740806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
60750806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
60760806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
607715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
607815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
607915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
60800806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
60810806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6083054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
6084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
6085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
608690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
608790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
608890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
608990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
609090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
609190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
609290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
609390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
609490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
609515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
609615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
609715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
609815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
609915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
610015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
610115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
6102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
6103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
6105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
6106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6110a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
6111a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
6112609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
61135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
6114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
61153fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                err = mCodec->fillBuffer(info);
61160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
61170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
61180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
61190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
61205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
61215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
612231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
6123ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim            sp<MediaCodecBuffer> buffer = info->mData;
6124577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
6125b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
6126697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                // pretend that output format has changed on the first frame (we used to do this)
6127697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
61281734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
6129697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                }
6130b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
61315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
6132ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim            buffer->setFormat(mCodec->mOutputFormat);
6133b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
6134d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mCodec->usingSecureBufferOnEncoderOutput()) {
6135054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
6136d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get());
6137d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                if (secureBuffer != NULL) {
61387c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
61393e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    // handle is only valid on 32-bit/mediaserver process
61407c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
61417c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
6142d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    handle = (native_handle_t *)secureBuffer->getDestinationPointer();
61437c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
6144054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
61457e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setPointer("handle", handle);
61467e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeOffset", rangeOffset);
61477e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeLength", rangeLength);
6148fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            } else if (buffer->base() == info->mCodecData->base()) {
61497e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->setRange(rangeOffset, rangeLength);
61505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
61515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
61525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
61535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
61547e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                        info->mCodecData, buffer);
61555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
61565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
61575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
61585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
6159308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
6160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
616121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
6162d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang                if (IsIDR(info->mData->data(), info->mData->size())) {
6163496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
6164496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
61655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
616621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
61697e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                mCodec->mSkipCutBuffer->submit(buffer);
61708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
61717e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            buffer->meta()->setInt64("timeUs", timeUs);
6172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6173fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            info->mData.clear();
6174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6175dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mCodec->mBufferChannel->drainThisBuffer(info->mBufferID, flags);
61765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
61775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
6178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
61805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
61815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
618279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mCallback->onEos(mCodec->mInputEOSResult);
6183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
6184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6188777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
61890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
61900806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
61910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
61920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
61930806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6195777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6196777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6197777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6198777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
6199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6204f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
6205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
6206609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
62077e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<RefBase> obj;
620876d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    CHECK(msg->findObject("buffer", &obj));
620976d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
621076d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    int32_t discarded = 0;
621176d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim    msg->findInt32("discarded", &discarded);
621276d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim
6213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
62140806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
62150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
62160806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
62170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
62180806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
62190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
62200806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
62210806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6222fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    info->mData = buffer;
6223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
6224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
62256aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
622676d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim            && !discarded && buffer->size() != 0) {
62276fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
6228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
6229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6230dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        android_native_rect_t crop;
6231dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        if (buffer->format()->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
6232dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            // NOTE: native window uses extended right-bottom coordinate
6233dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            ++crop.right;
6234dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            ++crop.bottom;
6235dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            if (memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
6236dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                mCodec->mLastNativeWindowCrop = crop;
6237dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
6238dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
6239dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            }
6240dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        }
6241dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
6242dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        int32_t dataSpace;
6243dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        if (buffer->format()->findInt32("android._dataspace", &dataSpace)
6244dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                && dataSpace != mCodec->mLastNativeWindowDataSpace) {
6245dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            status_t err = native_window_set_buffers_data_space(
6246dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
6247dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mCodec->mLastNativeWindowDataSpace = dataSpace;
6248dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
6249dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        }
62502d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang        if (buffer->format()->contains("hdr-static-info")) {
62512d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang            HDRStaticInfo info;
62522d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang            if (ColorUtils::getHDRStaticInfoFromFormat(buffer->format(), &info)
62532d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang                && memcmp(&mCodec->mLastHDRStaticInfo, &info, sizeof(info))) {
62542d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang                setNativeWindowHdrMetadata(mCodec->mNativeWindow.get(), &info);
62552d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang                mCodec->mLastHDRStaticInfo = info;
62562d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang            }
62572d2a2967ce29281816b9ddb9434b3c0084e4ce52Chong Zhang        }
6258dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
625990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
626090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
62617e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
626290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
626390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
626490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
626590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
626690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6267fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
6268fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
6269c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
62707e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
6271c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
6272fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
6273fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
6274fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
6275fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
62765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
6277fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
62780806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
6279fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
628015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
62810806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
628215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
628315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
62840806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
6285cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
6286cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
6287264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
6288251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6289cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
629015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
629115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
6292cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
6293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
629476d73bce9a63b795c7b8edbeab861239ab2eed0fWonsik Kim        if (mCodec->mNativeWindow != NULL && (discarded || buffer->size() != 0)) {
629515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
629615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
62976fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
62986fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
6299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
6300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
6303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
6305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
6306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
6311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
6312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
6314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
6323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
6324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
6326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
6327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6328c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
6329609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
6330c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
633115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
63323fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    status_t err = mCodec->fillBuffer(info);
63333fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    if (err != OK) {
63340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
63350806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
6336c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
6337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6341777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
63430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
63440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
63450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
63460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6349777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6350777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6351777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6352777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
6353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6358f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
6359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
6363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
6364ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6365ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
63661d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        if (mCodec->mOMXNode != NULL) {
6367e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa            auto tOmxNode = mCodec->mOMXNode->getHalInterface();
6368e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa            tOmxNode->unlinkToDeath(mDeathNotifier);
63691d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        }
6370ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
6371ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
6372ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
6374ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
6375e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
6376ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
6377d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode.clear();
6378ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6379d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
6380d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
63815b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
63825b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6383ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6384c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6385c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6386f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
63995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
64005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
64015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
64025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
64035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
64045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6407c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6409c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
641054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
641154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
641279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            if (keepComponentAllocated) {
641379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mCallback->onStopCompleted();
641479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            } else {
641579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mCallback->onReleaseCompleted();
641679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            }
6417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6418c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
642379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onFlushCompleted();
6424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6425c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
642830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
642930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
643030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
643130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
643230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
643330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
643430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6442f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
64485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
64495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
64515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
64525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6453d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode == NULL);
64545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
64551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6456ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6457bb644123966bfa2f44c60710faaafa8fa6f0e920Wonsik Kim    sp<RefBase> obj;
6458bb644123966bfa2f44c60710faaafa8fa6f0e920Wonsik Kim    CHECK(msg->findObject("codecInfo", &obj));
6459bb644123966bfa2f44c60710faaafa8fa6f0e920Wonsik Kim    sp<MediaCodecInfo> info = (MediaCodecInfo *)obj.get();
646078165d3f45797079b06c876042b9b78039378121Wonsik Kim    if (info == nullptr) {
6461bb644123966bfa2f44c60710faaafa8fa6f0e920Wonsik Kim        ALOGE("Unexpected nullptr for codec information");
646278165d3f45797079b06c876042b9b78039378121Wonsik Kim        mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR);
646378165d3f45797079b06c876042b9b78039378121Wonsik Kim        return false;
64645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
646578165d3f45797079b06c876042b9b78039378121Wonsik Kim    AString owner = (info->getOwnerName() == nullptr) ? "default" : info->getOwnerName();
64661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6467bb644123966bfa2f44c60710faaafa8fa6f0e920Wonsik Kim    AString componentName;
6468bb644123966bfa2f44c60710faaafa8fa6f0e920Wonsik Kim    CHECK(msg->findString("componentName", &componentName));
6469bb644123966bfa2f44c60710faaafa8fa6f0e920Wonsik Kim
64701065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6471cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa    sp<IOMX> omx;
6472d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
64731065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6474201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
647578165d3f45797079b06c876042b9b78039378121Wonsik Kim    OMXClient client;
647678165d3f45797079b06c876042b9b78039378121Wonsik Kim    if (client.connect(owner.c_str()) != OK) {
647778165d3f45797079b06c876042b9b78039378121Wonsik Kim        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
647878165d3f45797079b06c876042b9b78039378121Wonsik Kim        return false;
64791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
648078165d3f45797079b06c876042b9b78039378121Wonsik Kim    omx = client.interface();
64811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
648278165d3f45797079b06c876042b9b78039378121Wonsik Kim    pid_t tid = gettid();
648378165d3f45797079b06c876042b9b78039378121Wonsik Kim    int prevPriority = androidGetThreadPriority(tid);
648478165d3f45797079b06c876042b9b78039378121Wonsik Kim    androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
648578165d3f45797079b06c876042b9b78039378121Wonsik Kim    err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
648678165d3f45797079b06c876042b9b78039378121Wonsik Kim    androidSetThreadPriority(tid, prevPriority);
648778165d3f45797079b06c876042b9b78039378121Wonsik Kim
648878165d3f45797079b06c876042b9b78039378121Wonsik Kim    if (err != OK) {
648978165d3f45797079b06c876042b9b78039378121Wonsik Kim        ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
6490c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
649152e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6492c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6493c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
649523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
6496e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa    auto tOmxNode = omxNode->getHalInterface();
6497e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa    if (!tOmxNode->linkToDeath(mDeathNotifier, 0)) {
6498e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa        mDeathNotifier.clear();
649923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
650023858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
650126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6502d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    notify->setInt32("generation", ++mCodec->mNodeGeneration);
6503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
650690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6507ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6508ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
65111713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
65120167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6516d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode = omxNode;
651779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCodec->mCallback->onComponentAllocated(mCodec->mComponentName.c_str());
6518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6519c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6520c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
65215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
65225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6523c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6524c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6525c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6527c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6532f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6533f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6534f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6535f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6536f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6537054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6538054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6539a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6540e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6541e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
65424e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
65436d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    mCodec->mGraphicBufferSource.clear();
6544054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6545c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6546c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6547c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6548c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6549c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6550c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6551c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6552c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
655354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6554f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6555f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6557c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
6560d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        (void)mCodec->mOMXNode->freeNode();
6561c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6562c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6563c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6564c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
656554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
656679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        if (keepComponentAllocated) {
656779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onStopCompleted();
656879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        } else {
656979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onReleaseCompleted();
657079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        }
657154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
657254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6573c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6574c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6575c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6576c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6577c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6578c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6579c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6581c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6582c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6583c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6584c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6585c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
65867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
65877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
65887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
65897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
65907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
65917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
65927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
65938f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6594d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
65958f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6596d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6597d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6598d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6599d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6600c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6601c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6602c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6603c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6607c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6608c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
661354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6614c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6615c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
662279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onFlushCompleted();
6623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6628c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6629c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6631c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6634c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
66355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
66365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
66375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6638d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode != NULL);
66395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
66400806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
66415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
66420806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
66430806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
66440806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
66450806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
66460806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
66475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6648c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6649c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6650c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6651251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
66535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
665579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCodec->mCallback->onComponentConfigured(mCodec->mInputFormat, mCodec->mOutputFormat);
6656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
66585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
66595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6660d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6661addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (mCodec->mGraphicBufferSource == NULL) {
6662addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return BAD_VALUE;
6663addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6664addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6665addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    android_dataspace dataSpace;
6666addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err =
6667addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6668addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != OK) {
6669addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Failed to get default data space");
6670addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
6671addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6672addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6673addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    err = statusFromBinderStatus(
6674addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace));
6675addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != OK) {
6676addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("[%s] Unable to configure for node (err %d)",
6677addf2cbb120346ae42e78fa739245a353db5edadChong Zhang              mCodec->mComponentName.c_str(), err);
6678addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
6679addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6680a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6681d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
66826d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
66836d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
66846d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mRepeatFrameDelayUs));
6685a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6686a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6687a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6688a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
66896d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6690d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6691a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6692a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6693a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
66946c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang    if (mCodec->mMaxPtsGapUs != 0ll) {
66953604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        OMX_PARAM_U32TYPE maxPtsGapParams;
66963604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        InitOMXParams(&maxPtsGapParams);
66973604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        maxPtsGapParams.nPortIndex = kPortIndexInput;
66986c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang        maxPtsGapParams.nU32 = (uint32_t)mCodec->mMaxPtsGapUs;
66993604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang
67003604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        err = mCodec->mOMXNode->setParameter(
67013604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang                (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
67023604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang                &maxPtsGapParams, sizeof(maxPtsGapParams));
670394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
670494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
670594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
67066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6707d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
67082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
67092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
67102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
67116c2d0add22ee72566623834bbfeb6170b4c94588Chong Zhang    if (mCodec->mMaxFps > 0 || mCodec->mMaxPtsGapUs < 0) {
67126d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
67136d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
671437b2b389139ed638831e49708c947863eef631efRonghua Wu
671537b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
671637b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
67176d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6718d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
671937b2b389139ed638831e49708c947863eef631efRonghua Wu        }
672037b2b389139ed638831e49708c947863eef631efRonghua Wu    }
672137b2b389139ed638831e49708c947863eef631efRonghua Wu
672222dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa    if (mCodec->mCaptureFps > 0. && mCodec->mFps > 0.) {
67236d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
67246d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setTimeLapseConfig(
672522dc508717c7767927064ec7c152def99e54adcbPawin Vongmasa                        mCodec->mFps, mCodec->mCaptureFps));
67262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
67272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
67282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
67296d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6730d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
67312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
67322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
673372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6734d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
67356d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
6736764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                mCodec->mGraphicBufferSource->setSuspend(true, -1));
673772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
673872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
673972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
67406d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6741d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
674294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
674394ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
674494ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6745c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6746d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode->getParameter(
6747d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6748c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6749c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6750c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6751c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6752c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6753b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6754b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
67556d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
67566d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
67576d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
67586d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
67596d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
67606d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
67616d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        *(ColorAspects *)colorAspectsBuffer->base())));
67626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
6763b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6764b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6765b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6766b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6767b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6768b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6769d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6770d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6771d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6772d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6773d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6774d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6775d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6776d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6777addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = mCodec->mOMX->createInputSurface(
6778addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            &bufferProducer, &mCodec->mGraphicBufferSource);
6779d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6780d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6781d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6782d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6783d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
67847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
678579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onInputSurfaceCreated(
678679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mInputFormat,
678779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mOutputFormat,
67887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
67897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
67907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
67917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
67927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
67937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
67947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
679579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onInputSurfaceCreationFailed(err);
67967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
67977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
67987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
679979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimvoid ACodec::LoadedState::onSetInputSurface(const sp<AMessage> &msg) {
68008f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6801d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6802d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6803d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6804c1cddb57983c7b97284c61cf340c6b9a45d9a5fdMarco Nelissen    if (obj == NULL) {
6805c1cddb57983c7b97284c61cf340c6b9a45d9a5fdMarco Nelissen        ALOGE("[%s] NULL input surface", mCodec->mComponentName.c_str());
6806c1cddb57983c7b97284c61cf340c6b9a45d9a5fdMarco Nelissen        mCodec->mCallback->onInputSurfaceDeclined(BAD_VALUE);
6807c1cddb57983c7b97284c61cf340c6b9a45d9a5fdMarco Nelissen        return;
6808c1cddb57983c7b97284c61cf340c6b9a45d9a5fdMarco Nelissen    }
6809c1cddb57983c7b97284c61cf340c6b9a45d9a5fdMarco Nelissen
6810d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6811addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    mCodec->mGraphicBufferSource = surface->getBufferSource();
6812addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = setupInputSurface();
6813b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6814b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
681579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onInputSurfaceAccepted(
681679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                mCodec->mInputFormat, mCodec->mOutputFormat);
6817addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    } else {
6818d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6819d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6820d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
68218f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6822d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
682379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onInputSurfaceDeclined(err);
6824d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6825d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6826d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6827c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
68285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
68295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6830d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
68310806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
68320806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
68330806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
68340806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
68350806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6840f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6844f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
68453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6847cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6848cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
684929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6850cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6851cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6852cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6853251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
685491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6855d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mCodec->mOMXNode->sendCommand(
6856d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
6857c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6858c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6859c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6860c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6861c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6862c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6863c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
686491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6865cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6868f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6870dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (err != OK) {
6871dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        return err;
6872dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
6873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6874dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
6875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6879dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mCodec->mCallback->onStartCompleted();
6880dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
6881dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    return OK;
6882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6884f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
688672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
68946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
68956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
68966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
68976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
68986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
68996463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
69006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
69016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
69026463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
69036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
69046463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
69056463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
69066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
69076463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
690879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onFlushCompleted();
69096463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
69106463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
69116463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6917f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
69220806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
69230806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
69240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
69250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
69260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
69270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
69280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
69290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
6932d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mCodec->mOMXNode->sendCommand(
6933d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateExecuting);
69340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69360806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
69370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
69380806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
69400806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6952f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6956f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
69573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6960f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
696272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6969d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6970d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6971d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6972d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6973d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6974d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6975d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6976d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6977d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
697879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            mCodec->mCallback->onFlushCompleted();
6979d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6980d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6981d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
69826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
69836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
69846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
69856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
69866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
69876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6993f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
69980806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
69990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
70000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
70010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
70020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
70030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
70050806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
7008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
7009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7020f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
7021349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
7022349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
7023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7025f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
7026ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
7027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7030054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
7031054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
7032054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
7033054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
7034054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
7035054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
7036054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
7037054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
7038054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
7039054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
7040054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
70414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
70424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7043054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
7044054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
7045054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
7046054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
70470806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
7048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
7049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
7050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
70520806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
70530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
70540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
70550806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
70560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
70570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
7061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
70630806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
70640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
70650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
70660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
70670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70700806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
7071349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
707215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
70733fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        status_t err = mCodec->fillBuffer(info);
70740806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
70750806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
70760806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
70770806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
70790806340688c937e7b78c2d89db3809274130df4eLajos Molnar
70800806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
70810806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
70820806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
7083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7085054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
7086c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
7087054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
7088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
7089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
7090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
7091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
7092f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
7093349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
70940806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
7095349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
7096349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
7097349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
7099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71003cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
7101777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
7102777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
7103777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
7104777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
71053cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
71063cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
71073cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
71083cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
71093cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
71103cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
7111349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7112349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
7113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7115f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
71163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
711790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
7118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
7119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7121f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
7122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
7128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
7129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
7130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
7131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
713254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
7133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
7134c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
7135349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
7136349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7137d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(
7138d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateIdle);
71390806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
71400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
71410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
71420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
71430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
71440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
71450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
71460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
71547a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
7155ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
7156d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
7157d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
7158d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
7159d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
7160d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
7161d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7162349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
7163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7164d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
71650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
71660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
71670806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
71680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
71690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
7176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
7178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7183496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
7184496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
7185496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
7186496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
7187496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
7188496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
7189496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7190496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
7191496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
7192496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
7193496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
7194a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
7195a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
7196a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
7197a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
7198a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7199a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
7200a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7201a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
7202a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
7203a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
7204a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
7205a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
7206a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7207a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
7208a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
7209a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7210a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
72117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
72127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
72136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
72147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
72157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
72167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
72177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
72184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7219054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
72204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
72214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
72224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
7223054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
72244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
7225054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
72264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
72274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
72284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
72294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
72304dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
7231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7239a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
7240a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
7241530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
7242a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7243a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
7244a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
7245a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
7246a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7247d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->setConfig(
7248a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
7249a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
7250a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
7251a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7252a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
7253a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7254a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
7255a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7256a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
7257a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7258a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
7259a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
726061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    int64_t timeOffsetUs;
726161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
72626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
72636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set input buffer time offset without surface",
72646d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
72656d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
72666d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
72676d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
72686d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
72696d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
727061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
727161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        if (err != OK) {
727261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            ALOGE("[%s] Unable to set input buffer time offset (err %d)",
727361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                mComponentName.c_str(),
727461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                err);
727561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            return err;
727661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
727761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    }
727861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
727972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
728072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
72816d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
72826d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set start time without surface",
72836d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
72846d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
72856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
72866d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
72876d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
72886d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
728972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
729072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
729172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
729272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
729372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
729472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
729572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7296e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
7297e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
72986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
72996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set suspend without surface",
73006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
73016d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
73026d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
7303e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
7304764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        int64_t suspendStartTimeUs = -1;
7305764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        (void) params->findInt64("drop-start-time-us", &suspendStartTimeUs);
73066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
7307764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                mGraphicBufferSource->setSuspend(dropInputFrames != 0, suspendStartTimeUs));
7308b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7309b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7310b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7311b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7312b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7313b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
7314b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7315764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    int64_t stopTimeUs;
7316764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (params->findInt64("stop-time-us", &stopTimeUs)) {
7317764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (mGraphicBufferSource == NULL) {
7318764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGE("[%s] Invalid to set stop time without surface",
7319764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    mComponentName.c_str());
7320764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            return INVALID_OPERATION;
7321764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
7322764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        status_t err = statusFromBinderStatus(
7323764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                mGraphicBufferSource->setStopTimeUs(stopTimeUs));
7324764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
7325764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (err != OK) {
7326764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            ALOGE("Failed to set parameter 'stop-time-us' (err %d)", err);
7327764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            return err;
7328764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
7329f72cefddf378909f360998852e41f49042711299Hangyu Kuang
7330f72cefddf378909f360998852e41f49042711299Hangyu Kuang        int64_t stopTimeOffsetUs;
7331f72cefddf378909f360998852e41f49042711299Hangyu Kuang        err = statusFromBinderStatus(
7332f72cefddf378909f360998852e41f49042711299Hangyu Kuang                mGraphicBufferSource->getStopTimeOffsetUs(&stopTimeOffsetUs));
7333f72cefddf378909f360998852e41f49042711299Hangyu Kuang
7334f72cefddf378909f360998852e41f49042711299Hangyu Kuang        if (err != OK) {
7335f72cefddf378909f360998852e41f49042711299Hangyu Kuang            ALOGE("Failed to get stop time offset (err %d)", err);
7336f72cefddf378909f360998852e41f49042711299Hangyu Kuang            return err;
7337f72cefddf378909f360998852e41f49042711299Hangyu Kuang        }
7338f72cefddf378909f360998852e41f49042711299Hangyu Kuang        mInputFormat->setInt64("android._stop-time-offset-us", stopTimeOffsetUs);
7339764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
7340764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
7341b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7342b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7343b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7344b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7345b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7346b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7347b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7348b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7349e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7350e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
735189f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis    int32_t rateInt = -1;
735289f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis    float rateFloat = -1;
735389f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis    if (!params->findFloat("operating-rate", &rateFloat)) {
735489f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis        params->findInt32("operating-rate", &rateInt);
735589f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis        rateFloat = (float) rateInt; // 16MHz (FLINTMAX) is OK for upper bound.
735689f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis    }
735789f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis    if (rateFloat > 0) {
735889f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis        status_t err = setOperatingRate(rateFloat, mIsVideo);
73598db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
736089f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis            ALOGI("Failed to set parameter 'operating-rate' (err %d)", err);
73618db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
73628db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
73638db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7364870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7365870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7366870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7367870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7368870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7369870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7370870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7371870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7372870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7373870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7374870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
737589999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    int32_t latency = 0;
737689999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    if (params->findInt32("latency", &latency) && latency > 0) {
737789999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        status_t err = setLatency(latency);
737889999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        if (err != OK) {
737989999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            ALOGI("[%s] failed setLatency. Failure is fine since this key is optional",
738089999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang                    mComponentName.c_str());
738189999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang            err = OK;
738289999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang        }
738389999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang    }
738489999206477b02597be9b5322d35e37b11ca7326Hangyu Kuang
738589f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis    // Ignore errors as failure is expected for codecs that aren't video encoders.
738689f8fc52bc10358f336ea5ed3e05ea6f80bb3c54Andrew Lewis    (void)configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
73870f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
738801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    return setVendorParameters(params);
738901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar}
739001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
739101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
739201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// the minimum number of characters to keep in |key| (even if it has trailing tags).
739301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// (Used to remove trailing 'value' tags in settings names, e.g. to normalize
739401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// 'vendor.settingsX.value' to 'vendor.settingsX')
739501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarstatic void removeTrailingTags(char *key, size_t minLength, const char *tag) {
739601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    size_t length = strlen(key);
739701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    size_t tagLength = strlen(tag);
739801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    while (length > minLength + tagLength
739901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            && !strcmp(key + length - tagLength, tag)
740001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            && key[length - tagLength - 1] == '.') {
740101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        length -= tagLength + 1;
740201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        key[length] = '\0';
740301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
740401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar}
740501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
740601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar/**
740701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar * Struct encompassing a vendor extension config structure and a potential error status (in case
740801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar * the structure is null). Used to iterate through vendor extensions.
740901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar */
741001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarstruct VendorExtension {
741101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config;  // structure does not own config
741201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    status_t status;
741301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
741401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // create based on an error status
741501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension(status_t s_ = NO_INIT) : config(nullptr), status(s_) { }
741601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
741701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // create based on a successfully retrieved config structure
741801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *c_) : config(c_), status(OK) { }
741901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar};
742001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
742101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar// class VendorExtensions;
742201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar/**
742301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar * Forward iterator to enumerate vendor extensions supported by an OMX component.
742401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar */
742501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarclass VendorExtensionIterator {
742601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar//private:
742701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    static constexpr size_t kLastIndex = ~(size_t)0; // last index marker
742801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
742901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    sp<IOMXNode> mNode;                   // component
743001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    size_t mIndex;                        // current android extension index
743101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    std::unique_ptr<uint8_t[]> mBacking;  // current extension's backing
743201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension mCurrent;             // current extension
743301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
743401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator(const sp<IOMXNode> &node, size_t index)
743501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        : mNode(node),
743601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar          mIndex(index) {
743701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mCurrent = retrieve();
743801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
743901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
744001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    friend class VendorExtensions;
744101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
744201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarpublic:
744301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // copy constructor
744401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator(const VendorExtensionIterator &it)
744501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        : VendorExtensionIterator(it.mNode, it.mIndex) { }
744601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
744701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // retrieves the current extension pointed to by this iterator
744801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension retrieve() {
744901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (mIndex == kLastIndex) {
745001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return NO_INIT;
745101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
745201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
745301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        // try with one param first, then retry if extension needs more than 1 param
745401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        for (size_t paramSizeUsed = 1;; ) {
745501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (paramSizeUsed > OMX_MAX_ANDROID_VENDOR_PARAMCOUNT) {
745601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return BAD_VALUE; // this prevents overflow in the following formula
745701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
745801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
745901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            size_t size = sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE) +
746001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                (paramSizeUsed - 1) * sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::param);
746101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            mBacking.reset(new uint8_t[size]);
746201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (!mBacking) {
746301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return NO_MEMORY;
746401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
746501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
746601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config =
746701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(mBacking.get());
746801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
746901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            InitOMXParams(config);
747001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->nSize = size;
747101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->nIndex = mIndex;
747201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->nParamSizeUsed = paramSizeUsed;
747301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            status_t err = mNode->getConfig(
747401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension, config, size);
747501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (err == OK && config->nParamCount > paramSizeUsed && paramSizeUsed == 1) {
747601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // reallocate if we need a bigger config
747701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                paramSizeUsed = config->nParamCount;
747801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                continue;
747901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            } else if (err == NOT_ENOUGH_DATA
748001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                   || (err != OK && mIndex == 0)) {
748101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // stop iterator on no-more signal, or if index is not at all supported
748201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                mIndex = kLastIndex;
748301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return NO_INIT;
748401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            } else if (err != OK) {
748501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return err;
748601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            } else if (paramSizeUsed != config->nParamSizeUsed) {
748701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                return BAD_VALUE; // component shall not modify size of nParam
748801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
748901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
749001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return config;
749101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
749201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
749301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
749401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // returns extension pointed to by this iterator
749501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtension operator*() {
749601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return mCurrent;
749701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
749801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
749901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // prefix increment: move to next extension
750001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator &operator++() { // prefix
750101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (mIndex != kLastIndex) {
750201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            ++mIndex;
750301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            mCurrent = retrieve();
750401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
750501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return *this;
750601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
750701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
750801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // iterator equality operators
750901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    bool operator==(const VendorExtensionIterator &o) {
751001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return mNode == o.mNode && mIndex == o.mIndex;
751101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
751201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
751301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    bool operator!=(const VendorExtensionIterator &o) {
751401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return !(*this == o);
751501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
751601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar};
751701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
751801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar/**
751901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar * Iterable container for vendor extensions provided by a component
752001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar */
752101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarclass VendorExtensions {
752201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar//private:
752301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    sp<IOMXNode> mNode;
752401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
752501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarpublic:
752601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensions(const sp<IOMXNode> &node)
752701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        : mNode(node) {
752801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
752901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
753001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator begin() {
753101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return VendorExtensionIterator(mNode, 0);
753201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
753301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
753401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    VendorExtensionIterator end() {
753501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return VendorExtensionIterator(mNode, VendorExtensionIterator::kLastIndex);
753601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
753701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar};
753801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
753901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarstatus_t ACodec::setVendorParameters(const sp<AMessage> &params) {
754001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    std::map<std::string, std::string> vendorKeys; // maps reduced name to actual name
754101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    constexpr char prefix[] = "vendor.";
754201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    constexpr size_t prefixLength = sizeof(prefix) - 1;
754301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // longest possible vendor param name
754401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    char reducedKey[OMX_MAX_STRINGNAME_SIZE + OMX_MAX_STRINGVALUE_SIZE];
754501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
754601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // identify all vendor keys to speed up search later and to detect vendor keys
754701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    for (size_t i = params->countEntries(); i; --i) {
754801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        AMessage::Type keyType;
754901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        const char* key = params->getEntryNameAt(i - 1, &keyType);
755001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (key != nullptr && !strncmp(key, prefix, prefixLength)
755101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // it is safe to limit format keys to the max vendor param size as we only
755201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // shorten parameter names by removing any trailing 'value' tags, and we
755301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // already remove the vendor prefix.
755401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                && strlen(key + prefixLength) < sizeof(reducedKey)
755501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                && (keyType == AMessage::kTypeInt32
755601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                        || keyType == AMessage::kTypeInt64
755701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                        || keyType == AMessage::kTypeString)) {
755801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            strcpy(reducedKey, key + prefixLength);
755901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            removeTrailingTags(reducedKey, 0, "value");
756001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            auto existingKey = vendorKeys.find(reducedKey);
756101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (existingKey != vendorKeys.end()) {
756201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                ALOGW("[%s] vendor parameter '%s' aliases parameter '%s'",
756301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                        mComponentName.c_str(), key, existingKey->second.c_str());
756401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // ignore for now
756501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
756601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            vendorKeys.emplace(reducedKey, key);
756701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
756801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
756901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
757001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // don't bother component if we don't have vendor extensions as they may not have implemented
757101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // the android vendor extension support, which will lead to unnecessary OMX failure logs.
757201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (vendorKeys.empty()) {
757301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return OK;
757401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
757501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
757601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
757701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey)];
757801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
757901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    status_t finalError = OK;
758001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
758101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // don't try again if component does not have vendor extensions
758201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (mVendorExtensionsStatus == kExtensionsNone) {
758301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return OK;
758401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
758501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
758601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    for (VendorExtension ext : VendorExtensions(mOMXNode)) {
758701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
758801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (config == nullptr) {
758901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return ext.status;
759001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
759101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
759201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mVendorExtensionsStatus = kExtensionsExist;
759301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
759401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
759501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        strcpy(key, (const char *)config->cName);
759601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        size_t nameLength = strlen(key);
759701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        key[nameLength] = '.';
759801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
759901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        // don't set vendor extension if client has not provided any of its parameters
760001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        // or if client simply unsets parameters that are already unset
760101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        bool needToSet = false;
760201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
760301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            // null-terminate param key
760401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
760501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
760601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            removeTrailingTags(key, nameLength, "value");
760701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            auto existingKey = vendorKeys.find(key);
760801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
760901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            // don't touch (e.g. change) parameters that are not specified by client
761001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (existingKey == vendorKeys.end()) {
761101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                continue;
761201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
761301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
761401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            bool wasSet = config->param[paramIndex].bSet;
761501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            switch (config->param[paramIndex].eValueType) {
761601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            case OMX_AndroidVendorValueInt32:
761701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            {
761801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                int32_t value;
761901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                config->param[paramIndex].bSet =
762001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_BOOL)params->findInt32(existingKey->second.c_str(), &value);
762101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                if (config->param[paramIndex].bSet) {
762201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    config->param[paramIndex].nInt32 = value;
762301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
762401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                break;
762501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
762601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            case OMX_AndroidVendorValueInt64:
762701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            {
762801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                int64_t value;
762901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                config->param[paramIndex].bSet =
763001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_BOOL)params->findAsInt64(existingKey->second.c_str(), &value);
763101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                if (config->param[paramIndex].bSet) {
763201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    config->param[paramIndex].nInt64 = value;
763301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
763401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                break;
763501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
763601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            case OMX_AndroidVendorValueString:
763701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            {
763801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                AString value;
763901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                config->param[paramIndex].bSet =
764001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_BOOL)params->findString(existingKey->second.c_str(), &value);
764101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                if (config->param[paramIndex].bSet) {
764269f360e8f1517abfc298a3d6c7252c72269dc6c6Lajos Molnar                    size_t dstSize = sizeof(config->param[paramIndex].cString);
764369f360e8f1517abfc298a3d6c7252c72269dc6c6Lajos Molnar                    strncpy((char *)config->param[paramIndex].cString, value.c_str(), dstSize - 1);
764469f360e8f1517abfc298a3d6c7252c72269dc6c6Lajos Molnar                    // null terminate value
764569f360e8f1517abfc298a3d6c7252c72269dc6c6Lajos Molnar                    config->param[paramIndex].cString[dstSize - 1] = '\0';
764601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
764701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                break;
764801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
764901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            default:
765001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                ALOGW("[%s] vendor parameter '%s' is not a supported value",
765101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                        mComponentName.c_str(), key);
765201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                continue;
765301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
765401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (config->param[paramIndex].bSet || wasSet) {
765501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                needToSet = true;
765601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
765701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
765801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
765901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (needToSet) {
766001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            status_t err = mOMXNode->setConfig(
766101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    (OMX_INDEXTYPE)OMX_IndexConfigAndroidVendorExtension,
766201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    config, config->nSize);
766301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (err != OK) {
766401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                key[nameLength] = '\0';
766501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                ALOGW("[%s] failed to set vendor extension '%s'", mComponentName.c_str(), key);
766601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                // try to set each extension, and return first failure
766701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                if (finalError == OK) {
766801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    finalError = err;
766901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
767001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
767101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
767201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
767301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
767401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (mVendorExtensionsStatus == kExtensionsUnchecked) {
767501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mVendorExtensionsStatus = kExtensionsNone;
767601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
767701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
767801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    return finalError;
767901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar}
768001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
768101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnarstatus_t ACodec::getVendorParameters(OMX_U32 portIndex, sp<AMessage> &format) {
768201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    constexpr char prefix[] = "vendor.";
768301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    constexpr size_t prefixLength = sizeof(prefix) - 1;
768401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    char key[sizeof(OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE::cName) +
768501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            sizeof(OMX_CONFIG_ANDROID_VENDOR_PARAMTYPE::cKey) + prefixLength];
768601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    strcpy(key, prefix);
768701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
768801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    // don't try again if component does not have vendor extensions
768901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (mVendorExtensionsStatus == kExtensionsNone) {
769001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        return OK;
769101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
769201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
769301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    for (VendorExtension ext : VendorExtensions(mOMXNode)) {
769401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *config = ext.config;
769501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (config == nullptr) {
769601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            return ext.status;
769701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
769801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
769901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mVendorExtensionsStatus = kExtensionsExist;
770001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
770101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        if (config->eDir != (portIndex == kPortIndexInput ? OMX_DirInput : OMX_DirOutput)) {
770201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            continue;
770301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
770401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
770501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        config->cName[sizeof(config->cName) - 1] = '\0'; // null-terminate name
770601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        strcpy(key + prefixLength, (const char *)config->cName);
770701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        size_t nameLength = strlen(key);
770801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        key[nameLength] = '.';
770901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
771001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        for (size_t paramIndex = 0; paramIndex < config->nParamCount; ++paramIndex) {
771101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            // null-terminate param key
771201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            config->param[paramIndex].cKey[sizeof(config->param[0].cKey) - 1] = '\0';
771301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            strcpy(key + nameLength + 1, (const char *)config->param[paramIndex].cKey);
771401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            removeTrailingTags(key, nameLength, "value");
771501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            if (config->param[paramIndex].bSet) {
771601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                switch (config->param[paramIndex].eValueType) {
771701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                case OMX_AndroidVendorValueInt32:
771801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                {
771901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    format->setInt32(key, config->param[paramIndex].nInt32);
772001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    break;
772101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
772201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                case OMX_AndroidVendorValueInt64:
772301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                {
772401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    format->setInt64(key, config->param[paramIndex].nInt64);
772501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    break;
772601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
772701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                case OMX_AndroidVendorValueString:
772801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                {
772901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    config->param[paramIndex].cString[OMX_MAX_STRINGVALUE_SIZE - 1] = '\0';
773001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    format->setString(key, (const char *)config->param[paramIndex].cString);
773101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    break;
773201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
773301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                default:
773401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    ALOGW("vendor parameter %s is not a supported value", key);
773501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                    continue;
773601c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar                }
773701c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar            }
773801c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        }
773901c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
774001c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
774101c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    if (mVendorExtensionsStatus == kExtensionsUnchecked) {
774201c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar        mVendorExtensionsStatus = kExtensionsNone;
774301c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    }
774401c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar
774501c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2Lajos Molnar    return OK;
7746a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7747a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
77486507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
77496d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err = INVALID_OPERATION;
77506d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (mGraphicBufferSource != NULL) {
77516d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
77526d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
775379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCallback->onSignaledInputEOS(err);
77546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
77556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
77564ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kimvoid ACodec::forceStateTransition(int generation) {
77574ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    if (generation != mStateGeneration) {
77584ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        ALOGV("Ignoring stale force state transition message: #%d (now #%d)",
77594ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim                generation, mStateGeneration);
77604ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        return;
77614ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    }
77624ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    ALOGE("State machine stuck");
77634ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    // Error must have already been signalled to the client.
77644ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
77654ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    // Deferred messages will be handled at LoadedState at the end of the
77664ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    // transition.
77674ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    mShutdownInProgress = true;
77684ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    // No shutdown complete callback at the end of the transition.
77694ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    mExplicitShutdown = false;
77704ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    mKeepComponentAllocated = true;
77714ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
77724ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    status_t err = mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
77734ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    if (err != OK) {
77744ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        // TODO: do some recovery here.
77754ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    } else {
77764ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        changeState(mExecutingToIdleState);
77774ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim    }
77784ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim}
77794ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
778090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
778190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
778290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
778390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
778490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7785f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7792b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7793b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
779431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7795054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7796d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                CHECK_EQ(mCodec->mOMXNode->sendCommand(
7797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7800349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7803b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7804b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7805ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7824f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7829f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7840f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
78464ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        case kWhatShutdown: {
78474ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            if (mCodec->mFatalError) {
78484ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim                sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
78494ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim                msg->setInt32("generation", mCodec->mStateGeneration);
78504ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim                msg->post(3000000);
78514ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            }
78524ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            // fall-through
78534ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        }
7854349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7855e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7857349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
78583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7859349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7860349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78664ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        case kWhatForceStateTransition:
78674ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        {
78684ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            int32_t generation = 0;
78694ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            CHECK(msg->findInt32("generation", &generation));
78704ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            mCodec->forceStateTransition(generation);
78714ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
78724ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            handled = true;
78734ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            break;
78744ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        }
78754ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
7876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7884f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
78853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
788990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
789090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
789190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
789290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
789390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
789490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7895f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
79010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
79020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
79030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
79040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
79090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
79100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
79110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
79120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
79130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
7914e7b894297aebc24939ddfa632ea3dd2d405d9f93Pawin Vongmasa                    mCodec->mAllocator[kPortIndexOutput].clear();
79150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
7918d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mCodec->mOMXNode->sendCommand(
7919d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_CommandPortEnable, kPortIndexOutput);
79200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
79230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
79240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
79250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
7926dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    mCodec->mCallback->onOutputBuffersChanged();
79270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7928cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
79290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7930251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
79314ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim                    ALOGE("Error occurred while disabling the output port");
7932cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7936777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7937777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7938777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7939777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
79410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7943349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7944349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7945349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7946349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
79564ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            return BaseState::onOMXEvent(event, data1, data2);
7957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7962f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
79635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
79645778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7967f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
79750806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7981349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang            mCodec->deferMessage(msg);
7982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7994f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
79953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
799631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
79975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7998b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8001f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
8002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
8004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
8005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
80060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
80070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
80080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
80090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
80100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
80110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
80120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
80130806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
8014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
80155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
80165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
8018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
8020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
8021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8022349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
8023349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
8024349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
8025349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
8026349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
8027349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
8028349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
8029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
8030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
8031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
80330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
8034f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
80355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
8036d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mCodec->mOMXNode->sendCommand(
8037d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
80380806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
80390806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
80400806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
80410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
80420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
80430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
80440806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
8045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
80460167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
80470167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
8048bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
8049bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
8050bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
8051bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
8052b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
8053bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
8054bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
80550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
80560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
80570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
80580806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
80590806340688c937e7b78c2d89db3809274130df4eLajos Molnar
8060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
8061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8064f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
8065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
8066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
8067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
8069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8071f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
8072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
8073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
8074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
8076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
8079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8080f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
8081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
8082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8084f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
8085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
8086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
8088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
8089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
8090349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang            mCodec->deferMessage(msg);
8091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
8092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
8093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
8094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
8096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
8097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
8098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
80990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
8100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
8101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
8102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
8104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
8105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
8106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
8109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8111f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
81123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
8113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
8116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
8118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
8119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
81200806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
81210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
81220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
81230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
81240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
81250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
81260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
81270806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
8128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
8130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
8132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
8133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
8135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
8136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
8140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8141f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
8142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
8143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8145f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
81463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
8147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
8149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8151f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
8152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
8153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
8155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
8156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
8157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
81584ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            if (mCodec->mFatalError) {
81594ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim                sp<AMessage> msg = new AMessage(ACodec::kWhatForceStateTransition, mCodec);
81604ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim                msg->setInt32("generation", mCodec->mStateGeneration);
81614ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim                msg->post(3000000);
81624ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            }
8163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
8164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
8165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
8167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
8168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
8169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
8170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
8171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
8172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81734ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        case kWhatForceStateTransition:
81744ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        {
81754ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            int32_t generation = 0;
81764ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            CHECK(msg->findInt32("generation", &generation));
81774ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            mCodec->forceStateTransition(generation);
81784ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
81794ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            handled = true;
81804ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim            break;
81814ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim        }
81824ec8d83215d61ce8dfad15f5c42e7a190d924bf6Wonsik Kim
8183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
8184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
8185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
8186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
8189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8191f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
8192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
8193ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
8194ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
8195d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
8196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
8197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
8198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
81990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
82000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
82010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
82020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
82030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
82040806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
8205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
8207777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
8208777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
8209777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
8210777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
8211777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
8212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
8213e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
82140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
8215e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
8216e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
8217777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
8218777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
8219777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
8220777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
8221777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
8222777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
8223777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
8224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
8226777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
8227777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
8228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
8229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
8231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
8232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8233349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
8234349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
82351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
8236349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
8237d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            msg->setInt32("generation", mCodec->mNodeGeneration);
8238349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
8239349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
8240349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
8241349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
82423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
8243349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
8244349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
8245349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
8246349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
8247349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
8248349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
8249349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
8250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
8251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
8252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
8255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8257f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
8258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
8259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
8261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8263f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
8264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
8265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
8267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8269f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
8270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
8271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
8272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
82737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
82747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
82757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
82767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
827790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
827890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
827979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        mCodec->mCallback->onFlushCompleted();
8280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
8282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
8283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8284dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
8285dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
8286f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
8287f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
8288f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
8289f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
8290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
8291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
8293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
8295cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa        const char* owner, const char* name, const char* mime, bool isEncoder,
8296cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa        MediaCodecInfo::CapabilitiesWriter* caps) {
8297cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa    const char *role = GetComponentRole(isEncoder, mime);
82985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
82995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
83005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
83015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
83025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
8303cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa    status_t err = client.connect(owner);
83045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
83055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
83065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
83075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
83085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
83095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
8310d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
83115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
8312cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa    err = omx->allocateNode(name, observer, &omxNode);
83135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
83145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
83155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
83165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
83175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
8318d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = SetComponentRole(omxNode, role);
83195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
8320d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode->freeNode();
83215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
83225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
83235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
83245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
8325cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa    bool isVideo = strncasecmp(mime, "video/", 6) == 0;
8326816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    bool isImage = strncasecmp(mime, "image/", 6) == 0;
83275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
8328816e5eb2e9f9f18e001bbf7eab36654a1db2b168Chong Zhang    if (isVideo || isImage) {
83295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
83305b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
83315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
83325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
83336e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
83346e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
8335d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
8336d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoProfileLevelQuerySupported,
83375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
83385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
83395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
83405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
8341cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa            caps->addProfileLevel(param.eProfile, param.eLevel);
83426e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
834306e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar            // AVC components may not list the constrained profiles explicitly, but
834406e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar            // decoders that support a profile also support its constrained version.
834506e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar            // Encoders must explicitly support constrained profiles.
8346cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa            if (!isEncoder && strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC) == 0) {
834706e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar                if (param.eProfile == OMX_VIDEO_AVCProfileHigh) {
8348cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa                    caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedHigh, param.eLevel);
834906e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar                } else if (param.eProfile == OMX_VIDEO_AVCProfileBaseline) {
8350cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa                    caps->addProfileLevel(OMX_VIDEO_AVCProfileConstrainedBaseline, param.eLevel);
835106e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar                }
835206e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar            }
835306e98369b3db1d5d93d582d4d5b49c9d2a3ae455Lajos Molnar
83546e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
83556e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
8356cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa                        name, index,
83576e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
83586e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
83595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
83605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
83615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
83625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
83635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
83645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
83655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
836636e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
83676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
83686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
8369d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
8370d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoPortFormat,
83715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
83725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
83735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
83745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
83755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
83765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
83771ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim            if (IsFlexibleColorFormat(
8378d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
83795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
8380cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa                caps->addColorFormat(flexibleEquivalent);
83815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
8382cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa            caps->addColorFormat(portFormat.eColorFormat);
83836e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
83846e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
83856e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
8386cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa                        name, index,
83876e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
83886e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
83895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
8390cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa    } else if (strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC) == 0) {
83915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
83925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
83935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
83945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
83956e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
83966e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
8397d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
8398d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
83995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
84005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
84015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
84025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
84035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
8404cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa            caps->addProfileLevel(param.eProfile, 0 /* level */);
84056e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
84066e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
84076e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
8408cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa                        name, index,
84096e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
84106e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
84115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
84125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
84135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
84145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
84155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
8416cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa            ALOGW("component %s doesn't support profile query.", name);
84175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
84185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
84195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
84205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
84215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
8422d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->configureVideoTunnelMode(
8423d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
84245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
8425cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
84265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
8427d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else if (omxNode->setPortMode(
8428d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
8429d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                omxNode->prepareForAdaptivePlayback(
8430d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE,
84315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
8432cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
84335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
84345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
84355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
84365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
84375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
84385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
84395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
84405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
8441d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->getConfig(
8442d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
84435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
8444cbdeea977b79c41910b004cffcb80d81265853e8Pawin Vongmasa            caps->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
84455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
84465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
84475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
8448d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    omxNode->freeNode();
84495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
84505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
84515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
84525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
8453a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
8454a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
8455a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
8456a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
8457a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
8458a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
8459a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
8460a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8461a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
8462a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8463a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8464a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8465a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
8466a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8467a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8468a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8469a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8470a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
8471a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8472a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8473a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
8474a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
8475a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8476a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
8477a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8478a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8479a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8480a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
8481a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
8482a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8483a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
8484a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8485a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8486a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8487a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
8488a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
8489a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
8490a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8491a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
8492a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8493a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8494a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8495a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
8496a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
8497a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
8498a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
8499a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8500a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
8501a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
8502a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
8503a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
8504a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
8505a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
8506a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
8507a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
8508a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
8509a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
8510a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
8511a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
8512a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
8513a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
8514a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
8515a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
8516a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
8517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
8518