ACodec.cpp revision 349b8b4c47817a565ded94ff351caf48782f1252
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
4090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar#include <media/stagefright/MediaCodec.h>
41afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
45b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
473fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang#include <media/OMXBuffer.h>
483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
53777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar#include "include/DataConverter.h"
574811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim#include "include/SecureBuffer.h"
587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include "include/SharedMemoryBuffer.h"
5973dd808754c641fe798273d356ee38368715fa7bLajos Molnar#include "omx/OMXUtils.h"
60496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
61f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangusing binder::Status;
646d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
656e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnarenum {
666e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar};
686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhangstatic inline status_t statusFromBinderStatus(const Status &status) {
996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (status.isOk()) {
1006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return OK;
1016d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1026d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err;
1036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.serviceSpecificErrorCode()) != OK) {
1046d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if ((err = status.transactionError()) != OK) {
1076d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        return err;
1086d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
1096d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    // Other exception
1106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    return UNKNOWN_ERROR;
1116d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang}
1126d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
114251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
117251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
12626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
12726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
12826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
129984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    virtual ~MessageList() {
130984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    }
13126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
13226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
13326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
13426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
13526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
13626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
13726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
1385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnarstatic sp<DataConverter> getCopyConverter() {
1395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
1405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    static sp<DataConverter> sCopyConverter;        // zero-inited
1415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
1425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return sCopyConverter;
1435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar}
1445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
15326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
154984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        if (messages.empty()) {
155984a54322f7c70bc75e862d91bdd975814872affLajos Molnar            return;
156984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        }
157984a54322f7c70bc75e862d91bdd975814872affLajos Molnar
158984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        sp<AMessage> notify = mNotify->dup();
15926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
16126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
16226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
16526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
16626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
16726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
16826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
17026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
17126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
17226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
17326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
17626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
17726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
17826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
17926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
18026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
18326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
18426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
18626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
18726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
18826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
18926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
19126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
19226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
19426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
19526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
19626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
19726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
19826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
19926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
20026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
20126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
20490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
20590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
20690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
20790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
20890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
20990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
21090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
21190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
21226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
21326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
21426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
21526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
21626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
21726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
21826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
21926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
234090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
25726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
26126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
26226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
26326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
26426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
26526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
26615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
27215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
27315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
27690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
285090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit DeathNotifier(const sp<AMessage> &notify)
286ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
287ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
288ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
289ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
290ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
291ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
292ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
293ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
294ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
295ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
296ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
297ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
298ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
299ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
300ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
301ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
303090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit UninitializedState(ACodec *codec);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
314ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
321090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedState(ACodec *codec);
322c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
323c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
328c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
329c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3328f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
336d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
337d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
340c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
344090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit LoadedToIdleState(ACodec *codec);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
360090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToExecutingState(ACodec *codec);
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
374090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingState(ACodec *codec);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
376054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
377054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
385349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
386349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
39390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
396349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
397349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
404090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit OutputPortSettingsChangedState(ACodec *codec);
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
41290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
421090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ExecutingToIdleState(ACodec *codec);
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
443090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit IdleToLoadedState(ACodec *codec);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
458090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit FlushingState(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    bool mFlushComplete[2];
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
48015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
48115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
48215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
48315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
48415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
48515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
48615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
48915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
49015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
49115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
49215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
49315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
49415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
49515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
49615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
49715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
49815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
49915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
50015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
50215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
50315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
50415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
50515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
50615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
50715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
50815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
50915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
51015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
511f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
512b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    : mSampleRate(0),
513d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang      mNodeGeneration(0),
514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
515e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
516fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
5178db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
519346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
5209806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
52154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
522f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang      mIsLegacyVP9Decoder(false),
5239806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
5249806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
525e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5269806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
527054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
528054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
529054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
5305b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar      mNumUndequeuedBuffers(0),
53194ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
53337b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
5342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
535609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
536ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
5378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
538db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
539db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang      mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0) {
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
541c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
554dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
557d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
558d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
559fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
560fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
564f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
567f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
571f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
579a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
580a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
581a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
582a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
6001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
6011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
6031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
6041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
6061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
6071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
6091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
6107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6128f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
613d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
6148f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
615d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
616d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
617d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
618d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
6201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
6217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
6227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6235778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
6241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
627f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
6287a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6291d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
632f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
64030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
64130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
64330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
646496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
648496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
649496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
655054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
657054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
658054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
672e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
691e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
692098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    // no need to reconnect as we will not dequeue all buffers
693098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(
694d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            nativeWindow, &usageBits, !storingMetadataInDecodedBuffers());
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
699f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
700e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
701e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
702e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
703e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
704e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
705e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
735dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
736dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
737dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
743054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
745598c14420eefb2df4b50d9dd55bbf99bbc35e95ePawin Vongmasa            ALOGV("skipping buffer");
7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
760d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (!storingMetadataInDecodedBuffers()) {
7611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
76215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
76615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
76715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
7771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
7781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
780484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
781484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
782484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
783484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
784484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
786e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
7871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
790d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhangstatus_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
791d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    status_t err = mOMXNode->setPortMode(portIndex, mode);
792d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK) {
793d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
794d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                mComponentName.c_str(),
795d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                portIndex == kPortIndexInput ? "input" : "output",
796d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                asString(mode),
797d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                err);
798d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        return err;
799d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    }
800d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
801d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[portIndex] = mode;
802d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    return OK;
803d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang}
804d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
813d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (storingMetadataInDecodedBuffers()) {
814054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
816054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
8185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
8195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
8205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
823d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
824d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
827d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            const IOMX::PortMode &mode = mPortMode[portIndex];
8285b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t bufSize = def.nBufferSize;
829d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // Always allocate VideoNativeMetadata if using ANWBuffer.
830d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // OMX might use gralloc source internally, but we don't share
831d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            // metadata buffer with OMX, OMX has its own headers.
832d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mode == IOMX::kPortModeDynamicANWBuffer) {
833054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
834d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            } else if (mode == IOMX::kPortModeDynamicNativeHandle) {
8353e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                bufSize = sizeof(VideoNativeHandleMetadata);
836054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
837054219874873b41f1c815552987c10465c34ba2bLajos Molnar
8385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t conversionBufferSize = 0;
8395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
8405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            sp<DataConverter> converter = mConverter[portIndex];
8415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (converter != NULL) {
8425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // here we assume sane conversions of max 4:1, so result fits in int32
8435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (portIndex == kPortIndexInput) {
8445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->sourceSize(bufSize);
8455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                } else {
8465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    conversionBufferSize = converter->targetSize(bufSize);
8475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
848054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
849054219874873b41f1c815552987c10465c34ba2bLajos Molnar
85028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
85128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
852d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
854d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode),
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            // verify buffer sizes to avoid overflow in align()
8585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
85928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
86028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
86128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
86228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
86328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
86428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
8655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t alignedConvSize = align(conversionBufferSize, alignment);
8665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
86734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
86834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
86934e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
87028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
8715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
872d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mode != IOMX::kPortModePresetSecureBuffer) {
873d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
874d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            }
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
876fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            const sp<AMessage> &format =
877fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                    portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
878054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
879d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                sp<IMemory> mem;
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
881ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
882ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
88315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
88490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                if (mode == IOMX::kPortModePresetSecureBuffer) {
887a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
8881b40f2804a27b695e9e53fb1699b64cb0dd387f9Lajos Molnar                    sp<NativeHandle> native_handle;
889d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->allocateSecureBuffer(
890d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            portIndex, bufSize, &info.mBufferID,
891a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
892a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
8934811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                    info.mData = (native_handle == NULL)
8944811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            ? new SecureBuffer(format, ptr, bufSize)
8954811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            : new SecureBuffer(format, native_handle, bufSize);
8965b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    info.mCodecData = info.mData;
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
898d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    mem = mDealer[portIndex]->allocate(bufSize);
899d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    if (mem == NULL || mem->pointer() == NULL) {
900d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                        return NO_MEMORY;
901d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    }
902ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
903d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    err = mOMXNode->useBuffer(portIndex, mem, &info.mBufferID);
9045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
905d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    if (mode == IOMX::kPortModeDynamicANWBuffer) {
906054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
907054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
9085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
909d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    info.mCodecData = new SharedMemoryBuffer(format, mem);
910d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    info.mCodecRef = mem;
911d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
9125b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // if we require conversion, allocate conversion buffer for client use;
9135b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    // otherwise, reuse codec buffer
9145b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (mConverter[portIndex] != NULL) {
9155b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        CHECK_GT(conversionBufferSize, (size_t)0);
9165b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mem = mDealer[portIndex]->allocate(conversionBufferSize);
9175b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        if (mem == NULL|| mem->pointer() == NULL) {
9185b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            return NO_MEMORY;
9195b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        }
9207e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                        info.mData = new SharedMemoryBuffer(format, mem);
9215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = mem;
9225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else {
9235b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mData = info.mCodecData;
9245b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        info.mMemRef = info.mCodecRef;
9255b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
9291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
9301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
938d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
941eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
942eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
943eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
945eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
9464811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        desc->addBuffer(info.mBufferID, info.mData);
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
949eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
955e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
956098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
957098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        bool reconnect) {
9581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
962d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
963d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
9641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
9661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
970d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getGraphicBufferUsage(kPortIndexOutput, &usage);
9711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
9721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
9731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
9741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
9751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
9771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
9791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
9801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
982f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
983e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
984b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
985fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
986fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
987fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar
9881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
9891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
9901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
9911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
9921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
9931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
9941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
995098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            usage,
996098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            reconnect);
9971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
9981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
10001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
1001098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        OMX_U32 *minUndequeuedBuffers, bool preregister) {
1002098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar
10031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
10041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
10051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
10061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1007d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
1008d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
10091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
10101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
1011098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        err = setupNativeWindowSizeFormatAndUsage(
1012098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar                mNativeWindow.get(), &mNativeWindowUsageBits, preregister /* reconnect */);
10131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
1015e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
10161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
10171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
10181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
1019ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
1020ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
1021ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
1022ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1023ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
1024ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
1025d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1026d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1027ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1028ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
1029ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
1030ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
1031ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
1032ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1033ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1034054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
1035258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
1036258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
1037054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
1038258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1039258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
104029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
1041258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
1042258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
1043258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1044258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1045e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
1046e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
10471faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
10481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
1049e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1050e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
1051e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
1052e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
1053e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
1054e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
1055e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
10561faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
10571faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
1058e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
1059e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1060258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1061d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
1062d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
1063258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1064e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1065e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1066e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1067e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1068e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1069609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1070e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1071e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1072e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1073258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1074258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1075258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1076258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
108129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1092d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    // This method only handles the non-metadata mode (or simulating legacy
1093d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    // mode with metadata, which is transparent to ACodec).
1094d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    CHECK(!storingMetadataInDecodedBuffers());
10953fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1098098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
1099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1100054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1101e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
11033fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    static_cast<Surface*>(mNativeWindow.get())
11043fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            ->getIGraphicBufferProducer()->allowAllocation(true);
11053298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1106609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
11128ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
111315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
111415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
111629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
112174006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
112274006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
112315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
112415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
112590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
112674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
11273fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
11283fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode
11293fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        //       OMX doesn't use the shared memory buffer, but some code still
11303fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        //       access info.mData. Create an ABuffer as a placeholder.
1131d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1132d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mCodecData = info.mData;
11333fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
113474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
113574006804065941841883c4b46ee785070164023fJamie Gennis
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
11373fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId);
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1139609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
114074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
114574006804065941841883c4b46ee785070164023fJamie Gennis
1146609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1154d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK) {
1155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
11563fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        // that were dequeued. Also cancel all if we're in legacy metadata mode.
1157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
115874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
11673175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
11683175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
11693175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
11703175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
11713175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
11723fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11753fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    static_cast<Surface*>(mNativeWindow.get())
11763fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            ->getIGraphicBufferProducer()->allowAllocation(false);
11773fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1181054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1182d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    CHECK(storingMetadataInDecodedBuffers());
11833fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
1184054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1186098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers,
11873fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            false /* preregister */);
1188d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (err != OK)
1189054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1190e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1192e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1193e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1194e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1195e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1196e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1197e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
119815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
119990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1200e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1201e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1202e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1203d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
1204349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang
1205349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang        // Initialize fence fd to -1 to avoid warning in freeBuffer().
1206349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang        ((VideoNativeMetadata *)info.mData->base())->nFenceFd = -1;
1207349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang
12085b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        info.mCodecData = info.mData;
1209e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1210d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID);
1211e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1212e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1213d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        ALOGV("[%s] allocated meta buffer with ID %u",
1214d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                mComponentName.c_str(), info.mBufferID);
1215e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1216e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1217054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1218054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1219054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1220054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1221054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1222054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1223054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1224054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1225054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1226054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
12270806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1228054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
12290806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1231609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1232054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1233054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1234054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
123515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
12363fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    return fillBuffer(info);
1237054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1238054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
123915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
124015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
124115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
124215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
124315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
124415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
124515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
124615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
124715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
124815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
12490806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
12500806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
12510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
12520806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
12530806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
12540806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
12550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
12560806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
12570806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
12580806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
12590806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
12600806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
12610806340688c937e7b78c2d89db3809274130df4eLajos Molnar
12620806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
12630806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
12640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
12650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
12660806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
12670806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
12680806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
12690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
12700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
12710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
12720806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
12730806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
12740806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1278609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
128315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
128415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12863fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
12873fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
12880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12913fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
129590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
129690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
129790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
129890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
129990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
130090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
130190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
130290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
130390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
130490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
130590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
130690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
130790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
130890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
130990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
131090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
131190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
131290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = mNotify->dup();
131390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
131490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
131590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
131690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
131790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
131890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
131990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1320604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1321604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1322604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1323604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1324604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1325604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
132690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
132790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
132890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
132990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
133090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->post();
133190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
133290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
133390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1334f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
13358ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1336054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1337ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1338ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1339ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1340ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1341ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1342ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1343ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1344346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1345346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1346346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1347346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1348346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
134915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1350dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
135115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
135215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
135315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1354dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1355dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1357dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1358b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1359b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1360dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1361dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1362dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
136390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1364dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1365dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1366dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1367dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1368dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1369dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1370dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1371dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1372dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1373dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1374dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1375dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
137690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1377dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1378dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
137915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
138090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1381dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1382dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1383dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1385dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1386dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1387dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1388dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1389dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1390d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (!stale && !storingMetadataInDecodedBuffers()) {
1391dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1392dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1393dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1394dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1395dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1396dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1398dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1399054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1400dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1401dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1402b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1403b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1404dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1405dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1406054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1407054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1408054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1409054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1410054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1411054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1412054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1413054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1414054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
14160806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
14170806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
14180806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1419054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1420054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14210806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
14220806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
14230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
142415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
142590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
142690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1427d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
1428d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p",
1429d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1430d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mDequeueCounter - oldest->mDequeuedAt,
1431d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            oldest->mGraphicBuffer->getNativeBuffer());
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
143390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
14340806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1438777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1439938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1440938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1441777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1442777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1443777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1444777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14470806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1449777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1452349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1453777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1454938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1455938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14592ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
14602ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
14612ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
14622ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1463777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1464777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1465777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1466777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1470777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
14750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
1478d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL
1479fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            && info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
1480fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim        int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd;
148115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
148215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
148315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
148415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
148515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
148615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
14870806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
14880806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
14890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
14900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
14910806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
14920806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14940806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
1495d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->freeBuffer(portIndex, info->mBufferID);
14960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
14970806340688c937e7b78c2d89db3809274130df4eLajos Molnar
14980806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
14990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
15000806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
15010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
150415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
150515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
150615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
150715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1508604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1509604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1510604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1511604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
151290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1513d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    // remove buffer even if mOMXNode->freeBuffer fails
1514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1515777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1518f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
15190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1531777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15353fd200feb657c157125e45e30c2a7262e3c0244dChong Zhangstatus_t ACodec::fillBuffer(BufferInfo *info) {
15363fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    status_t err;
1537d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    if (!storingMetadataInDecodedBuffers()) {
15383fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->fillBuffer(
15393fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            info->mBufferID, OMXBuffer::sPreset, info->mFenceFd);
15403fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    } else {
15413fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        err = mOMXNode->fillBuffer(
15423fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang            info->mBufferID, info->mGraphicBuffer, info->mFenceFd);
15433fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    }
15443fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
15453fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    info->mFenceFd = -1;
15463fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    if (err == OK) {
15473fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
15483fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    }
15493fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang    return err;
15503fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang}
15513fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
15541ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime);
15555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
15565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
15575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
1558d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = SetComponentRole(mOMXNode, role);
15595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
15605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
15615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
15625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
15635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
15645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
15655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1573b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1574b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1576e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1579d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
1580d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
15818db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
15892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
15902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
15912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
159596bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    // propagate bitrate to the output so that the muxer has it
159696bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    if (encoder && msg->findInt32("bitrate", &bitRate)) {
159796bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // Technically ISO spec says that 'bitrate' should be 0 for VBR even though it is the
159896bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        // average bitrate. We've been setting both bitrate and max-bitrate to this same value.
159996bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("bitrate", bitRate);
160096bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar        outputFormat->setInt32("max-bitrate", bitRate);
160196bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar    }
160296bdf620189622005e83b4f1421c4f25b7fa1729Lajos Molnar
1603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
16053e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
16063e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && storeMeta != kMetadataBufferTypeInvalid) {
1607d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        IOMX::PortMode mode;
1608d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
1609d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mode = IOMX::kPortModeDynamicNativeHandle;
1610d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
1611d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                storeMeta == kMetadataBufferTypeGrallocSource) {
1612d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            mode = IOMX::kPortModeDynamicANWBuffer;
1613d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else {
1614d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            return BAD_VALUE;
1615d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        }
1616d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = setPortMode(kPortIndexInput, mode);
1617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1618054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
1619054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1620c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1621c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1622d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
1623d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1624c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1625c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1626c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1627c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1628054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1630308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
16313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
16323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
16333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
16343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
1635d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getExtensionIndex(
1636d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                "OMX.google.android.index.prependSPSPPSToIDRFrames", &index);
16373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
16393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
16403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
16413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
16423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1643d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(index, &params, sizeof(params));
16443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
16453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
16473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
16483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
16493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
16513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
16523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
16533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1654308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1655308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1656308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1657308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
16588db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1659308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1660308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
16613e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar            && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
1662308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1663d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        if (mFlags & kFlagIsSecure) {
1664d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            enable = OMX_TRUE;
1665d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        }
1666308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1667d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        err = setPortMode(kPortIndexOutput, enable ?
1668d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer);
1669308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1670d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            return err;
1671308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1672a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1673a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1674a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1675a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1676a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1677a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
167894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
16793604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        // only allow 32-bit value, since we pass it as U32 to OMX.
168094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
16812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
16823604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        } else if (mMaxPtsGapUs > INT32_MAX || mMaxPtsGapUs < 0) {
16833604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang            ALOGW("Unsupported value for max pts gap %lld", (long long) mMaxPtsGapUs);
16843604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang            mMaxPtsGapUs = -1ll;
16852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
16862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
168737b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
168837b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
168937b2b389139ed638831e49708c947863eef631efRonghua Wu        }
169037b2b389139ed638831e49708c947863eef631efRonghua Wu
16912c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
16922c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
169394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
169472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
169572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
169672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
169772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
169872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
169972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1700308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1701308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
17023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1703054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
17040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
17053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1706b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1707e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1708e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
17091713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
17101713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
17111713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
17121713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
17131713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
17141713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
17151713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
17161713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
17171713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
17181713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1719a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1720a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        if (mFlags & kFlagIsSecure) {
1721a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            // use native_handles for secure input buffers
1722d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer);
1723d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang
1724d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (err != OK) {
1725d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                ALOGI("falling back to non-native_handles");
1726d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
1727d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                err = OK; // ignore error for now
1728d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            }
1729a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1730e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
17313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
17321de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
17331de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
17345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17356597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
17366597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
17376597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
17386597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
17396597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
17406597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
17416597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
1742d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t temp = mOMXNode->setConfig(
1743d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
17446597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
17456597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
17466597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
17476597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
17486597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
17496597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
17506597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
17516597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
17526597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
17535a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
17545a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
17555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
17565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1757ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
17585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
175997827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
176097827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
17615a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
17625a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
17635a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
17645a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
176597827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
17665a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
17675a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1768fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1769fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1770d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1771d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1772d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1773d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1774d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mOMXNode->prepareForAdaptivePlayback(
1775d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1776d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1777d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1778d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
17793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
17803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1781d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1782d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1783d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1784d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1785d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1786d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
17875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1788ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1789ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1790ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
17913fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
17923fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
17933fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
17943fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
17953fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
17963fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
17973fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
17983fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
17993fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
1800d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer);
18015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
18025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
18035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
18045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
18055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
18075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
18085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
18095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
18105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
18115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
18135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
18145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
18155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
18165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
18175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
18185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
18195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
18205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
18215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
18225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
18235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
18255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
18265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
18275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
18285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
18295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
18305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
1831d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->prepareForAdaptivePlayback(
1832d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
18335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
18345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
18355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
18365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
18385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
18395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
18405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
18415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1843d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                // Fall back to legacy mode (use fixed ANWBuffer)
1844d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer);
1845d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                if (err != OK) {
1846d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    return err;
1847d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                }
18485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
1849d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                ALOGV("[%s] setPortMode on output to %s succeeded",
1850d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                        mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer));
1851054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
18525a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1853fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
18540167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
18555a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
18565a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
18575a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
18585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
18595a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1861e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1862e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1863e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1864e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1865e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1866e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1867e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
18705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
18715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
18725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
18735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
1874308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
18753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
18763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
18773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
18783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
18793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
18803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
18813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
1883b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1885b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
18893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
18903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
18913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
18931de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
18943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
18953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
18973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
18983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
18993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
19003a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1901777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1903777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1904777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
19063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1907777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1908777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
19123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
19131ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                if (!IsFlexibleColorFormat(
1914d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
19153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
19163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
19173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
19183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
19193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
1920e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
19213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
19223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
1923d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    // TODO: implement adaptive-playback support for bytebuffer mode.
1924d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    // This is done by SW codecs, but most HW codecs don't support it.
1925d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
1926d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    inputFormat->setInt32("adaptive-playback", false);
19273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
19283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
19293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
19303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
1931b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
1932b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
19333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
19353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
19363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
19393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
19403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
194142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
194242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
194342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
194442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
194542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
194642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
194742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
194842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
194942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
195042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
195142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
195242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
195342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1960aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1961b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
19628045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
19632965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
19648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1965ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1966ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1967ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1968aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1969aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1970aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1971b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1972b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1973b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1974ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
19758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
19768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
19778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19782965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
19792965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
19802965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
19812965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
19828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
19838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
19858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
19878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
19898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
19918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
19938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
19958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
19978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
19998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20008045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
20018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20028045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2003ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
20044471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
20052965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
20062965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2008729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2010729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2012729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2013729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2014729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2015729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2016729de186450f78c099637e1fce743fe531862c52Andreas Huber
2017729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
202117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
202217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
202317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
202417c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
202517c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2028ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
20292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
20302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
20312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
20322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
20332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
20342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
20352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2036516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2037cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2038cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2039516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2040cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
20412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2042516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2043516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2044516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
20452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
20462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2047516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2048516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2049516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
20502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
20512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
20522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2053516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2054516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
20552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2056ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2057ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2058ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2059ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2060ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2061ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2062ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
20635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
2064ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
206597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
206697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
206797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
206897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
206997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
207097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
207197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
207297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
207397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
20748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
20758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
20768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
20778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
20788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
20798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
20808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
20818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
20828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2084729de186450f78c099637e1fce743fe531862c52Andreas Huber
20854471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
20864471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
20874471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
20884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
20898b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
20908b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
20918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
20929806555d3930be43e11106281dee354820ac1c88Andreas Huber
20938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
20948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
20958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
20968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
20979806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
20989806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
20999806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
21009806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
21019806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
21029806555d3930be43e11106281dee354820ac1c88Andreas Huber
2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21108b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
21118b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
21128b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
21138b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21148b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2115ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2116ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2117ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2118ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2119ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2120ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2121ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2122ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2123ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2124ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2125697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
21264e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2127b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
21284e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2129777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2130777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2131777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2132777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2133777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2134777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2135777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2136777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
21375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
21385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // create data converters if needed
21395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!video && err == OK) {
21405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
21415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (encoder) {
21425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
21435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
21445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexInput] != NULL) {
21455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mInputFormat->setInt32("pcm-encoding", pcmEncoding);
21465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
21475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        } else {
21485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
21495b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
21505b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            if (mConverter[kPortIndexOutput] != NULL) {
21515b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
21525b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            }
21535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
21545b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
21555b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21598b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
21608b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
21618b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
21628b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21638b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
21648b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
21658b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
2166d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t temp = mOMXNode->setConfig(
2167d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigPriority,
21688b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
21698b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
21708b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
21718b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21728b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
21738b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
21748b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2175ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2176ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2177ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2178ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2179ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2180ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2181ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2182ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2183ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2184ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2185ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2186ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2187ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2188ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2189ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2190ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2191ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2192ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2193ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2194d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2195d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2196ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2197ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2198ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2199ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2200ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2201ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2202ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2203870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2204870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2205870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2206870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2207d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getConfig(
2208d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2209870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2210870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2211870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2212870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2213870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2214870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2215870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2216870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2217870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2218870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2219d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2220d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2221870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2222870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2223870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2224870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2225870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2226870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2227870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2228870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2229870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2230870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2231870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2232d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2233d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2234870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2235870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2236870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2237870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2238870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2239870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2240870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2241870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2242870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2243870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2244870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2245870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2246870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2247870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2248870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2249870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2250870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2251d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setConfig(
2252d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2253870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2254870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2255870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2256870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2257870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2258870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2259870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2260870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2261870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2262870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2263870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2264870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2265870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2266870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2267870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2268870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2269870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2270870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2271870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2272870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2273870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2274870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2275870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2276870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2277870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2278870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2279d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2280d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
2281870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2282870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2283870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2284870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2285870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2286870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2287870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2288870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2289870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2290d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2291d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh,
2292d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &refreshParams, sizeof(refreshParams));
2293870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2294870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2295870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2296870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2297870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2298870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2299870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
23000f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnarstatus_t ACodec::configureTemporalLayers(
23010f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        const sp<AMessage> &msg, bool inConfigure, sp<AMessage> &outputFormat) {
23020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!mIsVideo || !mIsEncoder) {
23030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return INVALID_OPERATION;
23040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23060f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString tsSchema;
23070f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!msg->findString("ts-schema", &tsSchema)) {
23080f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return OK;
23090f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23100f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23110f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numLayers = 0;
23120f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    unsigned int numBLayers = 0;
23130f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    int tags;
23140f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    char dummy;
23150f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE pattern =
23160f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
23170f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
23180f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0) {
23190f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
23200f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
23210f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                    &numLayers, &dummy, &numBLayers, &dummy))
23220f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && (tags == 1 || (tags == 3 && dummy == '+'))
23230f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
23240f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        numLayers += numBLayers;
23250f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        pattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
23260f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
23270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGI("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
23280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
23290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layerParams;
23320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    InitOMXParams(&layerParams);
23330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    layerParams.nPortIndex = kPortIndexOutput;
23340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2335d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2336d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
2337d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            &layerParams, sizeof(layerParams));
23380f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23390f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
23400f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
23410f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (!(layerParams.eSupportedPatterns & pattern)) {
23420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return BAD_VALUE;
23430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numLayers = min(numLayers, layerParams.nLayerCountMax);
23460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    numBLayers = min(numBLayers, layerParams.nBLayerCountMax);
23470f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23480f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (!inConfigure) {
23490f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE layerConfig;
23500f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        InitOMXParams(&layerConfig);
23510f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPortIndex = kPortIndexOutput;
23520f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.ePattern = pattern;
23530f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nPLayerCountActual = numLayers - numBLayers;
23540f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.nBLayerCountActual = numBLayers;
23550f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerConfig.bBitrateRatiosSpecified = OMX_FALSE;
23560f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2357d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(
2358d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidVideoTemporalLayering,
23590f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerConfig, sizeof(layerConfig));
23600f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else {
23610f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.ePattern = pattern;
23620f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nPLayerCountActual = numLayers - numBLayers;
23630f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.nBLayerCountActual = numBLayers;
23640f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        layerParams.bBitrateRatiosSpecified = OMX_FALSE;
23650f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2366d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2367d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
23680f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                &layerParams, sizeof(layerParams));
23690f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23700f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23710f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    AString configSchema;
23720f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid) {
23730f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("android.generic.%u+%u", numLayers - numBLayers, numBLayers);
23740f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    } else if (pattern == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
23750f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        configSchema = AStringPrintf("webrtc.vp8.%u", numLayers);
23760f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23770f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23780f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
23790f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGW("Failed to set temporal layers to %s (requested %s)",
23800f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                configSchema.c_str(), tsSchema.c_str());
23810f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
23820f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
23830f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2384d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2385d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
23860f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            &layerParams, sizeof(layerParams));
23870f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23880f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err == OK) {
23890f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        ALOGD("Temporal layers requested:%s configured:%s got:%s(%u: P=%u, B=%u)",
23900f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                tsSchema.c_str(), configSchema.c_str(),
23910f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                asString(layerParams.ePattern), layerParams.ePattern,
23920f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                layerParams.nPLayerCountActual, layerParams.nBLayerCountActual);
23930f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
23940f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        if (outputFormat.get() == mOutputFormat.get()) {
23950f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            mOutputFormat = mOutputFormat->dup(); // trigger an output format change event
23960f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        }
23970f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        // assume we got what we configured
23980f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        outputFormat->setString("ts-schema", configSchema);
23990f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
24000f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    return err;
24010f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar}
24020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2408d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2409d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2421d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2422d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2428d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2429d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2435777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2436777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2437777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2438777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
24496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
2451d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2452d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPortFormat, &format, sizeof(format));
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
24626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
24636e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
24646e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
24656e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
24666e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
24676e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2470d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2471d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPortFormat, &format, sizeof(format));
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2475aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
24768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
24772965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
24782965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2479ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2480ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2481ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2482ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2503d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2504d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2513d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2514d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamPortDefinition, &def, sizeof(def));
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2524d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getParameter(
2525d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2543aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2545b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2546b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2547b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2548b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2549b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2550b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2551b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2552b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2553b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2554b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2555b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2556b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2557b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2558b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2559b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2560b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2561b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2562b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2563b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2564b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2565b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2566b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2567b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2568b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2569b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2570b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2572d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2573d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioAac, &profile, sizeof(profile));
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2586d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2587d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
2588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2595ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2596ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2597ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2598ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2599ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26018045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2602dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
26038045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
26048045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
26058045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
26068045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
26078045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
26088045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
26092965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
26108045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2611d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t res = mOMXNode->setParameter(
2612d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAac, &profile, sizeof(profile));
26138045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
26148045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
2615d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mOMXNode->setParameter(
2616d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
26178045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
26188045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
26198045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
26208045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
2621b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen    mSampleRate = sampleRate;
26228045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
262697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
262797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
262897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
262997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
263097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
263197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
263297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
263397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
263497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
263597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
263697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
263797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
263897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
263997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
264097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
264197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
264297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2643d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2644d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
264597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
264697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
264797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
264897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
264997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
265097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
265197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
265297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
2653d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2654d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3, &def, sizeof(def));
265597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
265697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
26578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
26588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
26598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
26608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
26618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
26638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
26648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
26678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
26688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
26698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
26728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
26738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
26748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2675d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2676d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
26778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
26798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
26808a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26818a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
26838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
26848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
2685d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
2686d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3, &def, sizeof(def));
26878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
26888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
27075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
27085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
27115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
27135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
27145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
27155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
27205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
27215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
27265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2735729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2736729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2738729de186450f78c099637e1fce743fe531862c52Andreas Huber
2739d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2740d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2741729de186450f78c099637e1fce743fe531862c52Andreas Huber
2742729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2743729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2744729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2745729de186450f78c099637e1fce743fe531862c52Andreas Huber
2746729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2749d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2750d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioAmr, &def, sizeof(def));
2751729de186450f78c099637e1fce743fe531862c52Andreas Huber
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2755729de186450f78c099637e1fce743fe531862c52Andreas Huber
27565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
27585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
27595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2760729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2761729de186450f78c099637e1fce743fe531862c52Andreas Huber
276217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2763777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2764777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2765777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2767729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
276817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2769729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2770729de186450f78c099637e1fce743fe531862c52Andreas Huber
27712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
27722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
27732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
27752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
27762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
27772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
27782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
2780d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
27812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
27822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
27832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
27842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
27852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
2786d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(OMX_IndexParamAudioFlac, &def, sizeof(def));
27872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
27882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
27892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
27902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
27912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
27922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
27942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
27952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
27962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
27972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
27982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2799729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
28005b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
2801729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2802729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2803729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2804729de186450f78c099637e1fce743fe531862c52Andreas Huber
2805d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
2806d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2807729de186450f78c099637e1fce743fe531862c52Andreas Huber
2808729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2809729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2810729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2811729de186450f78c099637e1fce743fe531862c52Andreas Huber
2812729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2813729de186450f78c099637e1fce743fe531862c52Andreas Huber
2814d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2815d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
2816729de186450f78c099637e1fce743fe531862c52Andreas Huber
2817729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2818729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2819729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2820729de186450f78c099637e1fce743fe531862c52Andreas Huber
2821729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2822729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2823729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2824729de186450f78c099637e1fce743fe531862c52Andreas Huber
2825d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
2826d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2827729de186450f78c099637e1fce743fe531862c52Andreas Huber
2828729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2829729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2830729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2831729de186450f78c099637e1fce743fe531862c52Andreas Huber
2832729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
28335b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    switch (encoding) {
28345b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm8bit:
28355b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataUnsigned;
28365b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 8;
28375b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28385b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcmFloat:
28395b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataFloat;
28405b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 32;
28415b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28425b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        case kAudioEncodingPcm16bit:
28435b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.eNumData = OMX_NumericalDataSigned;
28445b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            pcmParams.nBitPerSample = 16;
28455b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            break;
28465b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        default:
28475b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            return BAD_VALUE;
28485b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
2849729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2850729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2851729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2852729de186450f78c099637e1fce743fe531862c52Andreas Huber
2853c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2854c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2855729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2856729de186450f78c099637e1fce743fe531862c52Andreas Huber
2857d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
2858d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
28595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // if we could not set up raw format to non-16-bit, try with 16-bit
28605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    // NOTE: we will also verify this via readback, in case codec ignores these fields
28615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (err != OK && encoding != kAudioEncodingPcm16bit) {
28625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.eNumData = OMX_NumericalDataSigned;
28635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        pcmParams.nBitPerSample = 16;
2864d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
2865d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
28665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
28675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    return err;
2868729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2869729de186450f78c099637e1fce743fe531862c52Andreas Huber
28705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
287197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
28725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
28735a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2874d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->configureVideoTunnelMode(
2875d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
28765a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
28775a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
28785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
28795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
28805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
28815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
28825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
28835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
28845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
28855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
28865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
28875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
28885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
28895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
28905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
28940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
28950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2904d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2905d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat,
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2912229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2913229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
29140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
29151ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
2916d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
29170d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2918229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2919229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2920229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2921229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2922229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29476e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
29486e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
29496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
29506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
29516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
29526e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2959d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
2960d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
29660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
29670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
29680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
29690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
29700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
29710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
29720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
29730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
29740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
29750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
29760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
29770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
29780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
29790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
29800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
29850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
29860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
29890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
2990d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
2991d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_IndexParamVideoPortFormat, &format, sizeof(format));
29920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
29930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
29940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
29950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
29960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
29970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
29980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
29990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30000d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
30010d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
30020d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
30040d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30050d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30060d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
30070d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
30080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
30090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
30100d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
30110d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
30120d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
30130d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30140d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
30150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
30160d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
30171ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim                && IsFlexibleColorFormat(
3018d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        mOMXNode, format.eColorFormat, false /* usingNativeBuffers */,
30190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
30200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
30210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
30220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
30230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
3024d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
3025d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoPortFormat, &format, sizeof(format));
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3028e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
3029e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
3030e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
3031e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
3032e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
30332472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
3034e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
3035e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
3036e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
303794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
303894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
3039a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
3040e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
3041e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
3044e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3045e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3046e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3053e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3058e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3061e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3062e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3063e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3064e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3065e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3066e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3067e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3069e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3070e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3071e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
30725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3074a6bfb5060824f01041f956c733fec141504c280bHangyu Kuangstatus_t ACodec::setPortBufferNum(OMX_U32 portIndex, int bufferNum) {
3075a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
3076a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    InitOMXParams(&def);
3077a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nPortIndex = portIndex;
3078a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    status_t err;
3079a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    ALOGD("Setting [%s] %s port buffer number: %d", mComponentName.c_str(),
3080a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3081d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3082d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3083a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3084a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        return err;
3085a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3086a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    def.nBufferCountActual = bufferNum;
3087d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3088d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        OMX_IndexParamPortDefinition, &def, sizeof(def));
3089a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (err != OK) {
3090a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        // Component could reject this request.
3091a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        ALOGW("Fail to set [%s] %s port buffer number: %d", mComponentName.c_str(),
3092a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            portIndex == kPortIndexInput ? "input" : "output", bufferNum);
3093a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3094a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    return OK;
3095a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang}
3096a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
30988338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3099b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
310089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
310189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
310289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
310389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
310489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
310589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3113f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    if (compressionFormat == OMX_VIDEO_CodingVP9) {
3114f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
3115f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        InitOMXParams(&params);
3116f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nPortIndex = kPortIndexInput;
3117f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        // Check if VP9 decoder advertises supported profiles.
3118f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        params.nProfileIndex = 0;
3119d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
3120f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                OMX_IndexParamVideoProfileLevelQuerySupported,
3121d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
3122f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang        mIsLegacyVP9Decoder = err != OK;
3123f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang    }
3124f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
313389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
313489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
313589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
313689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
31370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
313889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
313989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
314089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
31410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
314289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
314389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
31440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
314589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3151a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component input buffer number to be |tmp|. If succeed,
3152a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set input port buffer number to be |tmp|. If fail,
3153a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3154a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-input-buffers", &tmp)) {
3155a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexInput, tmp);
3156a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3157a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3158a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3159a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
3160a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // Set the component output buffer number to be |tmp|. If succeed,
3161a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will set output port buffer number to be |tmp|. If fail,
3162a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    // component will keep the same buffer number as before.
3163a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    if (msg->findInt32("android._num-output-buffers", &tmp)) {
3164a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        err = setPortBufferNum(kPortIndexOutput, tmp);
3165a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang        if (err != OK)
3166a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang            return err;
3167a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang    }
3168a6bfb5060824f01041f956c733fec141504c280bHangyu Kuang
316978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
317078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
317178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
317278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
317378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
317478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
317578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
317678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
317778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
317978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3192b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3193b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3194b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
31958338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
31968338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3197db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3198db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3199db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        return err;
3200db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3201db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
32025e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
3203db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
3204db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        err = OK;
3205db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3206b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3207b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3208b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3209b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3210d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3211d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3212b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3213b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3214b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3215b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3216b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
32178338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3218b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3219b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3220b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3221d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
3222b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3223b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3224b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3225b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3226b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3227b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3228b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3229b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3230b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3231b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3232b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3233b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3234b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3235b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3236db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting color aspects failed even though codec advertises support",
3237b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
32388338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
32398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
32408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3241b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3242b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3243b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
32448338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
32458338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3246b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
32478338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3248b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3249b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3250b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3251b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3252b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3253b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3254b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
32558338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
32568338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3257b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
32588338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3259b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3260b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3261b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3262b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3263b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3264b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3265b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3266d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeColorAspectsIndex, &params, sizeof(params));
32678338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3268b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3269b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3271b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3272b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3273b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3274b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3275b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3276b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3277b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3278b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3279b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3280b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3281b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3282b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3283b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3284b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
32858338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3286b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
32948338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3297b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3298b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3299b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3300b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3301b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3302b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3303b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3304b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3305b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3306b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3307b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3308b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3309b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3310b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3311b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3312b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3313b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
33148338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3315b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3316b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3317b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3318b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3319b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3320b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3321b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3322b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3323b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3324b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3325b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3326b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3328b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3329b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3330b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3331b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3333b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3334b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3335b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3336b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3337b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3338b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3339b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3340b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
33418338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3342b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
33438338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3345b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3346b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3347b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3348b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3349b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3350b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3351b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
33528338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33538338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3354b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
33558338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
33568338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3357b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3358b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3359b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3360b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3361b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3362b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3363b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3364b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3365b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3367b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3368b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3369b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3377b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3378b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3379b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3380b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3381b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3382b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3383b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3384b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
33858338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33868338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3388b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3389b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3390b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3391b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3392b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3393b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3394b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3398b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
34025e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::setHDRStaticInfoForVideoCodec(
34035e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
34045e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
34055e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34065e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    DescribeHDRStaticInfoParams params;
34075e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    InitOMXParams(&params);
34085e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
34095e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34105e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    HDRStaticInfo *info = &params.sInfo;
34115e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (getHDRStaticInfoFromFormat(configFormat, info)) {
34125e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
34135e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
34145e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34155e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    (void)initDescribeHDRStaticInfoIndex();
34165e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
34175e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    // communicate HDR static Info to codec
34185e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    return setHDRStaticInfo(params);
34195e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang}
34205e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
3421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
34248338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
34258338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
34278338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
34288338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
34348338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3435b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3436b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
34378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3439b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3440b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3441b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3442b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3443b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3444b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3445b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3446b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3447b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
34488338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
34498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3450b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3451b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3452b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3453b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3454b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3455b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
34568338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3457b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3458b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3459b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3460b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3461b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3462b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3463b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3464b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
34658338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3466b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3467b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3468b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3469b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3470b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34735e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuangstatus_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
34745e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
3475db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    DescribeHDRStaticInfoParams params;
3476db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    InitOMXParams(&params);
34775e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    params.nPortIndex = portIndex;
3478db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3479db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = getHDRStaticInfo(params);
3480db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err == OK) {
3481db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        // we only set decodec output HDRStaticInfo if codec supports them
3482db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        setHDRStaticInfoIntoFormat(params.sInfo, format);
3483db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3484db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3485db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3486db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3487db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::initDescribeHDRStaticInfoIndex() {
3488d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getExtensionIndex(
3489d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            "OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
3490db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (err != OK) {
3491db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang        mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
3492db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3493db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3494db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3495db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3496db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
3497db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3498db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3499d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3500db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3501db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3502db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    const HDRStaticInfo *info = &params.sInfo;
3503db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGV("[%s] setting  HDRStaticInfo (R: %u %u, G: %u %u, B: %u, %u, W: %u, %u, "
3504db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "MaxDispL: %u, MinDispL: %u, MaxContentL: %u, MaxFrameAvgL: %u)",
3505db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str(),
3506db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mR.x, info->sType1.mR.y, info->sType1.mG.x, info->sType1.mG.y,
3507db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mB.x, info->sType1.mB.y, info->sType1.mW.x, info->sType1.mW.y,
3508db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxDisplayLuminance, info->sType1.mMinDisplayLuminance,
3509db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            info->sType1.mMaxContentLightLevel, info->sType1.mMaxFrameAverageLightLevel);
3510db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3511db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3512db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] setting HDRStaticInfo failed even though codec advertises support",
3513db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3514db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3515db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3516db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3517db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuangstatus_t ACodec::getHDRStaticInfo(DescribeHDRStaticInfoParams &params) {
3518db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    status_t err = ERROR_UNSUPPORTED;
3519db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    if (mDescribeHDRStaticInfoIndex) {
3520d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->getConfig(mDescribeHDRStaticInfoIndex, &params, sizeof(params));
3521db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    }
3522db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
3523db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeHDRStaticInfoIndex,
3524db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            "[%s] getting HDRStaticInfo failed even though codec advertises support",
3525db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang            mComponentName.c_str());
3526db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang    return err;
3527db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang}
3528db318d40b90a456311b3920c605e33b763ca79f9Hangyu Kuang
35298338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
35385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
35425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
35545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
35565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
35585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3559d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3560d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
35635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
35675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
35685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
35695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
35715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
35795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
35855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
35945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
35975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
35992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
36005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3604a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3605a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3606a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3607a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3608a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3610d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3611d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
36405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3641d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
3642d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
36435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
36495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
36525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3655d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3656d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
36575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
36605778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
36615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3665870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3666870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3667870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3668870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3669870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3670870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3671870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3672870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3673870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3674870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3675870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
36765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
36775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
36785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
36795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3689c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3690c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3691c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3692c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
369389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
369489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
36959bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            err = setupVPXEncoderParameters(msg, outputFormat);
369689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
369789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37020f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
37030f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
37040f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
37050f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
37068338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
37078338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3708b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3709b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
37108338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
37118338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
37128338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
37138338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
37145e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err != OK) {
37155e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        return err;
37165e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
37175e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
37185e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
37195e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    if (err == ERROR_UNSUPPORTED) { // support is optional
37205e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
37215e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang        err = OK;
37225e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang    }
37235e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang
37240f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
37250f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        return err;
37260f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
37270f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
37280f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    switch (compressionFormat) {
37290f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingAVC:
37300f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingHEVC:
37310f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            err = configureTemporalLayers(msg, true /* inConfigure */, outputFormat);
37320f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            if (err != OK) {
37330f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar                err = OK; // ignore failure
37340f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            }
37350f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
37360f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
37370f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP8:
37380f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        case OMX_VIDEO_CodingVP9:
37390f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // TODO: do we need to support android.generic layering? webrtc layering is
37400f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            // already set up in setupVPXEncoderParameters.
37410f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
37420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
37430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        default:
37440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar            break;
37450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
37460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
3747d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3748d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3749d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
37550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
37560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
37570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
37580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
37590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
37600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
37610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
37620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
37630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
37640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
37650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
37660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
37670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
37680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
37690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
37700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
37710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
37720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
37730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
37740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
37750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
37760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
37770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
37780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
37790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
37800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
37810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
37820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
37830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
37840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
3785d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->setParameter(
3786d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoIntraRefresh, &params, sizeof(params));
37870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
37880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
37890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
3790f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnarstatic OMX_U32 setPFramesSpacing(
379163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar        float iFramesInterval /* seconds */, int32_t frameRate, uint32_t BFramesSpacing = 0) {
3792f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // BFramesSpacing is the number of B frames between I/P frames
3793f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // PFramesSpacing (the value to be returned) is the number of P frames between I frames
3794f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3795f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // keyFrameInterval = ((PFramesSpacing + 1) * BFramesSpacing) + PFramesSpacing + 1
3796f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                                     ^^^                            ^^^        ^^^
3797f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                              number of B frames                number of P    I frame
3798f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3799f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //                  = (PFramesSpacing + 1) * (BFramesSpacing + 1)
3800f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //
3801f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // E.g.
3802f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //      I   P   I  : I-interval: 8, nPFrames 1, nBFrames 3
3803f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    //       BBB BBB
3804f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
3805f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    if (iFramesInterval < 0) { // just 1 key frame
3806f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        return 0xFFFFFFFE; // don't use maxint as key-frame-interval calculation will add 1
3807f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    } else if (iFramesInterval == 0) { // just key frames
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3810f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar
3811f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    // round down as key-frame-interval is an upper limit
3812f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    uint32_t keyFrameInterval = uint32_t(frameRate * iFramesInterval);
3813f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    OMX_U32 ret = keyFrameInterval / (BFramesSpacing + 1);
3814f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    return ret > 0 ? ret - 1 : 0;
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
381796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
381896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
381996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
382096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
382196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
382296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
382396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
382496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
382596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
38265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
382763a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
382863a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
38295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
383063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
383496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
383596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
38385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
38405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
38435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
38465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
38475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
38485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3849d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
3850d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
38515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3863f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nBFrames = 0;
3864f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, mpeg4type.nBFrames);
38655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
38665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
38675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
38695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
38715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
38745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
38765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
38775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
38785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
38795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
38835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
38855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
38865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
38895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
38905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3892d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3893d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
389996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
390963a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
391063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
39115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
391263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
39135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
39145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
391696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
391796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
39185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
39195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
39225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
39285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
39295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3931d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
3932d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
39335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3941f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nBFrames = 0;
3942f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h263type.nBFrames);
39435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
39445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
39455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
39485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
39495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
39505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
39515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
39525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
39555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
39575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
39585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
39655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
39665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3969d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
3970d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
397696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
39775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3985a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3986a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3987a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3988a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3989a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3990a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3991a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3992a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3993a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3994a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3995a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3996a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3997a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3998a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3999a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
4000a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
4001a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
4002a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
4003a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
4004a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
4005a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4006a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
4007a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
4008a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
4009a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
4010a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
4011a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
4012a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
4013a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
4014a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
4015a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
4016a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
4017a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
4018a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
4019a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
4020a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
4021a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
4022a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
4023a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
4024a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
4025a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
4026a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
4027a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
4028a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
4029a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
4030a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
4031a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
4032a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
4033a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
4034a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
4035a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
4036a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
40375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
403863a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
403963a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
40405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
404163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
40425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
40435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
404596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
404696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
40475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
40485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
40495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
40505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
40515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
40525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
40545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
40570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
40580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
40590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
40600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
40610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
40620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
40630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
40640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
40650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
40660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
40675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
40685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
40695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
40705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4071d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4072d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
40735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
40765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
40795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
40805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
40825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
40835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
40845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
40855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
40865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
40895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
40915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
40925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
40955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
4096e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else {
40978eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
40984c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#if 0   /* DON'T YET DEFAULT TO HIGHEST PROFILE */
40994c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar        // Use largest supported profile for AVC recording if profile is not specified.
4100826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        for (OMX_VIDEO_AVCPROFILETYPE profile : {
4101826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
4102826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            if (verifySupportForProfileAndLevel(profile, 0) == OK) {
4103826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                h264type.eProfile = profile;
4104826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar                break;
4105826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar            }
4106826cbe4d07c709f647cdd29354434df20e355c9aLajos Molnar        }
41074c6fe6676e726c22ed54e3dbe51aae03e902049eLajos Molnar#endif
41088eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang    }
41098eadd7737f422b0477bbacbb2663e3ef42c9fe51Hangyu Kuang
4110e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    ALOGI("setupAVCEncoderParameters with [profile: %s] [level: %s]",
4111e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            asString(h264type.eProfile), asString(h264type.eLevel));
4112e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang
41135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
41145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
41155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
41165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
41175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
4118f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
41195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
41205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
41215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
41225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
41235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
41245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
41255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
41275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
41285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
41295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
4130e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
4131e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
4132e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nSliceHeaderSpacing = 0;
4133e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
4134e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefFrames = 2;
4135e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nBFrames = 1;
4136f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4137e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nAllowedPictureTypes =
4138e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
4139e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
4140e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
4141e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
4142e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
4143e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bconstIpred = OMX_TRUE;
4144e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
4145e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
4146e98883f809d3eb7502f29d977a68179b3998e0d3Hangyu Kuang        h264type.nCabacInitIdc = 1;
41475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
41505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
41545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
41555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
41565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
41575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
41585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
41595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
41605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4161d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4162d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
41635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4168e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // TRICKY: if we are enabling temporal layering as well, some codecs may not support layering
4169e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // when B-frames are enabled. Detect this now so we can disable B frames if temporal layering
4170e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    // is preferred.
4171e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    AString tsSchema;
4172e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    int32_t preferBFrames = (int32_t)false;
4173e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    if (msg->findString("ts-schema", &tsSchema)
4174e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            && (!msg->findInt32("android._prefer-b-frames", &preferBFrames) || !preferBFrames)) {
4175e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE layering;
4176e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        InitOMXParams(&layering);
4177e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        layering.nPortIndex = kPortIndexOutput;
4178d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (mOMXNode->getParameter(
4179d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
4180e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                        &layering, sizeof(layering)) == OK
4181e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.eSupportedPatterns
4182e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                && layering.nBLayerCountMax == 0) {
4183e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nBFrames = 0;
4184e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate, h264type.nBFrames);
4185e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            h264type.nAllowedPictureTypes &= ~OMX_VIDEO_PictureTypeB;
4186e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            ALOGI("disabling B-frames");
4187d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            err = mOMXNode->setParameter(
4188d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
4189e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
4190e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            if (err != OK) {
4191e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar                return err;
4192e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar            }
4193e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar        }
4194e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar    }
4195e19f2956de379b9c9a852d50d83d0608ca42bfe9Lajos Molnar
419696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
41975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4199c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
420063a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    int32_t bitrate;
420163a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval;
4202c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
420363a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar            || !msg->findAsFloat("i-frame-interval", &iFrameInterval)) {
4204c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
4205c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4206c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4207c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
4208c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4209c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
4210c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
4211c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
4212c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
4213c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4214c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4215c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
4216c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4217c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4218c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
4219c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
4220c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
4221c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4222c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
4223d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->getParameter(
4224d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4225c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4226c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4227c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4228c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4229c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
4230c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
4231c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
4232c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
4233c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
4234c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4235c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4236c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
4237c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
4238c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
4239c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
4240c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4241c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
4242c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
4243c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
42449aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
4245f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
4246c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4247d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4248d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
4249c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
4250c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
4251c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
4252c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
4253c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
4254c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
4255c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
42569bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnarstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat) {
425789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
425863a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    float iFrameInterval = 0;
42594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
42604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
42614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
42624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
42634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
42644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
42654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
42664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
42674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
42684154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
426989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
427089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
427189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
427263a4d50f472ca67b3174ae51911091e44db6956eLajos Molnar    msg->findAsFloat("i-frame-interval", &iFrameInterval);
427389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
427489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
427589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
42764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
42774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
42784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
42794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
42804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
42814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
42824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
42834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
42844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
42854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
42869bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar    OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE tsType =
42879bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        OMX_VIDEO_AndroidTemporalLayeringPatternNone;
42889bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar
42894154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
4290f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numLayers = 0;
4291f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        unsigned int numBLayers = 0;
4292f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        int tags;
4293f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        char dummy;
4294f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        if (sscanf(tsSchema.c_str(), "webrtc.vp8.%u-layer%c", &numLayers, &dummy) == 1
4295f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0) {
42964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
42979bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC;
4298f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers;
4299f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        } else if ((tags = sscanf(tsSchema.c_str(), "android.generic.%u%c%u%c",
4300f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                        &numLayers, &dummy, &numBLayers, &dummy))
4301f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && (tags == 1 || (tags == 3 && dummy == '+'))
4302f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar                && numLayers > 0 && numLayers < UINT32_MAX - numBLayers) {
43034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
4304f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            // VPX does not have a concept of B-frames, so just count all layers
43059bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            tsType = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
4306f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            tsLayers = numLayers + numBLayers;
43074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
4308f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar            ALOGW("Ignoring unsupported ts-schema [%s]", tsSchema.c_str());
43094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
4310f1c70d7f5472e3f5680144c29c839108993996fdLajos Molnar        tsLayers = min(tsLayers, (size_t)OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS);
43114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
43124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
43134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
43144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
43154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
4316d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4317d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
43184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
43194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
43204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
43214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
4322f4b18f4872d353a1e114c890ec472608ff8f9edaLajos Molnar            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate) + 1;
43234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
43244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
43254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
43264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
43274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
43284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
43294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
43304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
43314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
43324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
43334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
43344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
43354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
43364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
4337d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        err = mOMXNode->setParameter(
4338d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
43394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
43404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
43414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
43429bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsType == OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC) {
43439bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // advertise even single layer WebRTC layering, as it is defined
43449bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("webrtc.vp8.%u-layer", tsLayers));
43459bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar        } else if (tsLayers > 0) {
43469bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            // tsType == OMX_VIDEO_AndroidTemporalLayeringPatternAndroid
43479bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar            outputFormat->setString("ts-schema", AStringPrintf("android.generic.%u", tsLayers));
43484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
43494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
43504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
435189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
435289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
435389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
43545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
43555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
43565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
43575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
43585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
43595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
43616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
4362d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->getParameter(
43635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
4364d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                &params, sizeof(params));
43655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
43675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
43685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
43695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
43715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
43725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
43745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
43755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
43766e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
43776e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
43786e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
43796e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
43806e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
43816e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
43825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43836e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
43845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
43855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
438696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
438796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
43885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
43895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
43905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
43915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4392d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4393d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
43945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
43965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
43975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
43985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
439996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
44005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
44015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4402d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4403d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoBitrate, &bitrateType, sizeof(bitrateType));
44045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
44075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
44085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
44095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
44105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4411d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4412d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
44135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
44145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
44165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
44175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
44185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
44205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
44215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
44225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
44235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
44245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4425d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setParameter(
4426d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamVideoErrorCorrection,
44275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
44285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
44295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
443278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
443378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4440d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(
4441d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4442777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4443777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4444777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4454777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4455777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4456777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4457777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
446578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
446678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
446778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4470d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = mOMXNode->setParameter(
4471d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            OMX_IndexParamPortDefinition, &def, sizeof(def));
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4476d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4477d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4478d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4479d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4480d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4481d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4482d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4483d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4484d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4485d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4486d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4487d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4488d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4489d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
44907e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
44917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
44927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
44937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
44947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
44957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
44967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
44977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
44987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
44997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
45007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
45027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
45037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
45047e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
45057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
45067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
45077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
45087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4509e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
45107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4511c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4512054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4513054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4514c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
45157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
45167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
45177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4525609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4555777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
455631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
455731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4558e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
455931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4560d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mOMXNode->getParameter(OMX_IndexParamPortDefinition, &def, sizeof(def));
4561777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4562777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4563777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
456431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4565777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4566777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4567777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4568777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
456931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
457031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
457131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
457231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
457331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4574e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4575e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4576e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4577e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4578e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4579e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4580e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4581e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4582e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4583e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
45840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
458573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
45860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
45870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
45880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
45890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
45900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
45910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
45920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
45930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
4594d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (DescribeColorFormat(mOMXNode, describeParams)) {
45950d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
45960d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
45970d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
45980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
45990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
46005a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
460173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
460273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
460373dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
460473dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
460573dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
460673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
460773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
46080d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
460903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
461003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4613b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4614b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4615b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4616b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4617b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4618b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4619d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                        if (mOMXNode->getConfig(
4620b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4621b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4622b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4623b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4624b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4625b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4626b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4627b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4628b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
462991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4630b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4631b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4632b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4633b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4634b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4635b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4636b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4637b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4638b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4639b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
464031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4641b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4642b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4643b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4644b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4645b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4646b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4647b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4648b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4649b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4650b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4651b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4652b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4653b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4654b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4655b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4656b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4657b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
46585e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
4659b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4660b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
46615e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        if (mConfigFormat->contains("hdr-static-info")) {
46625e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                            (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
46635e2f5c10dcedbddd0ea0255f049468760aa09048Hangyu Kuang                        }
4664777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4666e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4667e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
46684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
46694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
46704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
46714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
46724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
46734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
46744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
4675d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    status_t err = mOMXNode->getParameter(
46764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
46774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
46784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
46794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
46804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
46819bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                        if (vp8type.eTemporalPattern == OMX_VIDEO_VPXTemporalLayerPatternWebRTC
46829bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount > 0
46839bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                && vp8type.nTemporalLayerCount
46849bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        <= OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS) {
46859bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            // advertise as android.generic if we configured for android.generic
46869bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            AString origSchema;
46879bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            if (notify->findString("ts-schema", &origSchema)
46889bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                    && origSchema.startsWith("android.generic")) {
46899bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
46909bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "android.generic.%u", vp8type.nTemporalLayerCount));
46919bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                            } else {
46929bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                notify->setString("ts-schema", AStringPrintf(
46939bbbdd3cab5c6b93649cbf31ba3097218944b06aLajos Molnar                                        "webrtc.vp8.%u-layer", vp8type.nTemporalLayerCount));
46944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
46954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
46964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
46974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
46984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
46994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4700e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4702777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4703777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4704777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4705777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4706777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4708777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4709e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4710e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4712e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4714e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4715e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4716870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4717870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4718870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4719870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4720870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
472331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
47265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
47275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
47285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
47295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
473031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
473131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
473231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
473331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
473431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
473531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
473631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
473797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4744d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4745d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioPcm, &params, sizeof(params));
4746777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4747777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4748777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
474914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4750777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4751777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4752777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
47535b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %u channels%s, %u-bit",
4754777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4755777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
47565b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                params.nBitPerSample);
4757777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4758777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
47635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
47645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    AudioEncoding encoding = kAudioEncodingPcm16bit;
47655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (params.eNumData == OMX_NumericalDataUnsigned
47665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 8u) {
47675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcm8bit;
47685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.eNumData == OMX_NumericalDataFloat
47695b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            && params.nBitPerSample == 32u) {
47705b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        encoding = kAudioEncodingPcmFloat;
47715b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    } else if (params.nBitPerSample != 16u
47725b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                            || params.eNumData != OMX_NumericalDataSigned) {
47735b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
47745b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.eNumData), params.eNumData,
47755b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                                asString(params.ePCMMode), params.ePCMMode);
47765b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        return FAILED_TRANSACTION;
47775b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
47785b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    notify->setInt32("pcm-encoding", encoding);
4779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
47828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
47848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
47859806555d3930be43e11106281dee354820ac1c88Andreas Huber
4786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4790e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4792d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4793d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAac, &params, sizeof(params));
4794777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4795777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4796777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
48099806555d3930be43e11106281dee354820ac1c88Andreas Huber
4810d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4811d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioAmr, &params, sizeof(params));
4812777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4813777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4814777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
48180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
48210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4831e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4833d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4834d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioFlac, &params, sizeof(params));
4835777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4836777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4837777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4850e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4851d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4852d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioMp3, &params, sizeof(params));
4853777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4854777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4855777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4856e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4858e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4865e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4869d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4870d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_IndexParamAudioVorbis, &params, sizeof(params));
4871777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4872777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4873777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4874e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4875e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4876e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4878e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4879e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4880e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
488197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
488297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
488397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
488497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4885e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
488697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4887d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4888d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4889777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4890777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4891777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4892777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
489397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
489497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
489597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
489697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
489797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
489897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4899e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
49008a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
49018a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
49028a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
49038a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
49048a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
49058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4906d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4907d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4908777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4909777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4910777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4911777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
49128a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49138a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
49148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
49158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
49168a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
49178a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
49188a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
49198c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
49208c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
49218c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
49228c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
49238c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
49248c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4925d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4926d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4927777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4928777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4929777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4930777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
49318c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
49328c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
49338c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
49348c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
49358c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
49368c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
49378c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
493810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
493910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
494010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
494110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
494210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
494310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4944d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4945d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4948777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
494910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
495010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
495110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
495210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
495310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
495410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
495510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
495610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
495710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
495810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
495910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
496010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
496178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
496210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
496310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
496441d3f579d2c166984958263533284209b90c87d5Marco Nelissen
496541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
496641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
49670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
496841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
496941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
497041d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4971d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mOMXNode->getParameter(
4972d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                                OMX_IndexParamAudioPcm, &params, sizeof(params));
4973777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4974777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4975777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
497641d3f579d2c166984958263533284209b90c87d5Marco Nelissen
497741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
497841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
49790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
498041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
498110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
498210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4985777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4986777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4987e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
498831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
498931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
499031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
499131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4992777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4993777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
499431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
499531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4996e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4997e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4998e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4999b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
5000b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
5001b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
5002b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
5003b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5004b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
5005b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5006b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
5007b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5008b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5009b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
5010b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5011b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5012b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
5013b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5014b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5015b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
5016b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
5017b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
5018b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5019b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
5020b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
5021b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5022b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
5023b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
5024b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5025b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5026b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
5027b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
5028b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
5029b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
5030b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
5031b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
5032b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
5033b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
5034b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
5035b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
5036b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
5037b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
50381734c7d01c1567568ced29398b23abd601fd44cbLajos Molnarvoid ACodec::onOutputFormatChanged(sp<const AMessage> expectedFormat) {
5039697aedf61d6180e72102068a969383018eedfa1eLajos Molnar    // store new output format, at the same time mark that this is no longer the first frame
5040b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
5041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5042b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
5043777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
5044777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
5045777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
5046e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
50471734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    if (expectedFormat != NULL) {
50481734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> changes = expectedFormat->changesFrom(mOutputFormat);
50491734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        sp<const AMessage> to = mOutputFormat->changesFrom(expectedFormat);
50501734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        if (changes->countEntries() != 0 || to->countEntries() != 0) {
50511734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar            ALOGW("[%s] BAD CODEC: Output format changed unexpectedly from (diff) %s to (diff) %s",
50521734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mComponentName.c_str(),
50531734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    changes->debugString(4).c_str(), to->debugString(4).c_str());
50541734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar        }
50551734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar    }
50561734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar
50575b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    if (!mIsVideo && !mIsEncoder) {
50585b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
50595b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
50605b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
50615b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
50625b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
50635b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
50645b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        if (mConverter[kPortIndexOutput] != NULL) {
50655b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
50665b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar        }
50675b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    }
50685b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar
5069b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
5070b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
5071b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5072b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5073b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5074b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> &notify) {
5075e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
5076b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5077e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5078b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) {
5079b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // notify renderer of the crop change and dataspace change
5080e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
5081b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t left, top, right, bottom;
5082b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
5083b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setRect("crop", left, top, right + 1, bottom + 1);
5084b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5085b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5086b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t dataSpace;
5087b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
5088b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setInt32("dataspace", dataSpace);
5089b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
5090b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
5091b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
5092b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5093b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
5094b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
5095b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
5096b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5097b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
5098b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        int32_t channelCount, sampleRate;
509984d7e874983ee0d66db328c454fa603374d4635fMarco Nelissen        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
5100b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        CHECK(mOutputFormat->findInt32("sample-rate", &sampleRate));
5101b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        if (mSampleRate != 0 && sampleRate != 0) {
5102b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderDelay = mEncoderDelay * sampleRate / mSampleRate;
5103b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mEncoderPadding = mEncoderPadding * sampleRate / mSampleRate;
5104b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen            mSampleRate = sampleRate;
5105b6e9b8919c9ba25afc0f7f55ee3933f5d9f24dc8Marco Nelissen        }
5106e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
5107e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
5108e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
5109ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
5110e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
5111e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
5112b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
5113e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
5114e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
5115b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
5116b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
511731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
511831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
51195778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
5120cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
5121d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
5122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
5123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
5124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
5125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
5126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
5127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
5128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
5129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5132346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5133346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
5134346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
51355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
5136251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
5137cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
5138cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5139cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5140496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5141496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5142496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5143496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5144496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5145496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5146496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5147496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5148496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5149496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5150496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5151d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    return mOMXNode->setConfig(
5152496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5153496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5154496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5155496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5156496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
51577e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim////////////////////////////////////////////////////////////////////////////////
51587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
51597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik KimACodec::PortDescription::PortDescription() {
51607e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim}
51617e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
5162eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
51634811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        IOMX::buffer_id id, const sp<MediaCodecBuffer> &buffer) {
5164eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
5165eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
5166eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5167eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5168eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
5169eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
5170eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5171eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5172eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
5173eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
5174eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5175eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
51767e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimsp<MediaCodecBuffer> ACodec::PortDescription::bufferAt(size_t index) const {
5177eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
5178eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5179eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5180eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
5181eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5182f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5187ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5188ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5192f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
520626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
520726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
520826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
520926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
521026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5211e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5212e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5213e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5214e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5215e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5216e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
521926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
52231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
52241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
52251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
52261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
52281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
52291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52302235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
52311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
52331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
52341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
52351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
52361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
52371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
52387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
52398f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
52407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
52417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5242251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
52437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
52447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
52457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
52467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
52477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5248ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5249ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5250251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5251ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
52526d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            mCodec->mGraphicBufferSource.clear();
5253ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5254ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5255ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5256ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
525730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
525830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
525930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
526030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
5261d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->freeNode();
526230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
526330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
526430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
5265349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang            notify->setInt32("what", CodecBase::kWhatReleaseCompleted);
526630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
526730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
526830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
526930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
527726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
52785e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
52795e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5280d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode == NULL) {
52815e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
52825e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
528326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
52845e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
52855e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5286d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    int32_t generation;
5287d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(msg->findInt32("generation", (int32_t*)&generation));
5288d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (generation != mCodec->mNodeGeneration) {
5289d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        ALOGW("Unexpected message for component: %s, gen %u, cur %u",
5290d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                msg->debugString().c_str(), generation, mCodec->mNodeGeneration);
5291777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5292777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
529326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
529426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
529526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
529626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
529726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
529826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
529926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
530026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
530190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
530226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
530326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5304e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5305e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
530690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
530790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
530890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
530990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
531090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
531190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
531290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
531390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
531490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
531590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
531626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
531726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
531826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
531926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
532026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
532126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
532226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
53330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
53340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
53350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
53360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
53370af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
53380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
53390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
53400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
53410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
53420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
535215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
535315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5354609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
535515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
535715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5363609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
536515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
537215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
537815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
537915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
538290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
538390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
538490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
538590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
538690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
538790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
538890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
538990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
539090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
539190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
539290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5394777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5395777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
540090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
540190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
540290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
540390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
540490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5405f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5407b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
54086cf9a1238986880536de705255f7c2c91c1ba719Chong Zhang        ColorAspects aspects = ColorUtils::unpackToColorAspects(data2);
5409b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5410b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5411b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5412b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5415ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5421ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5423251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5424251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5425251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5426251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5427251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5428251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5429251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5435ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5436349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5437349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
54380806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
54390806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
54400806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
54410806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
54420806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
544315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
544415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
544515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
54460806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
54470806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
545015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
545115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
545215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
545315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
545415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
545515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
545615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
545796e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
545896e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
545996e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
546096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
546196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
546296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5463d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5474777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5476777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5477777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5483f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
5491d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
5492609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
5493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5494ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim    info->mData->setFormat(mCodec->mInputFormat);
5495ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim    notify->setObject("buffer", info->mData);
5496fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    info->mData.clear();
5497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
5499609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
5500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
5502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
5504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5508f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5510609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
55117e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
5512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
55135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5514a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
55155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55167e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<RefBase> obj;
55177e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    if (!msg->findObject("buffer", &obj)) {
5518a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
5519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
5520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
55227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
55237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
55247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
55257fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
55267fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
55277fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
55287fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
55297e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    } else {
55307e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer = static_cast<MediaCodecBuffer *>(obj.get());
5531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
55345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
55355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
55365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
55375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
55385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
55400806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
55410806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
55420806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
55430806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
55440806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
55450806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
55460806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5549fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    info->mData = buffer;
5550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5555dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5556dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5557dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5558dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
55655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5566fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5567fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5568fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5569fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5570fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5571fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5577d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                int32_t isCSD = 0;
5578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5579f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    if (mCodec->mIsLegacyVP9Decoder) {
5580f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        ALOGV("[%s] is legacy VP9 decoder. Ignore %u codec specific data",
5581f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                            mCodec->mComponentName.c_str(), bufferID);
5582f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        postFillThisBuffer(info);
5583f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                        break;
5584f88dc1865408506f69c858818ea05f5248ff4462Hangyu Kuang                    }
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
55895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
55905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
55915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5592fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                size_t size = buffer->size();
5593fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                if (buffer->base() != info->mCodecData->base()) {
5594ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5595d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
5597fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                         buffer->base(), info->mCodecData->base());
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55995b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
5600d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (converter == NULL || isCSD) {
56015b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        converter = getCopyConverter();
56025b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    }
56035b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    status_t err = converter->convert(buffer, info->mCodecData);
56045b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    if (err != OK) {
56055b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, err);
56060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
56070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5608fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                    size = info->mCodecData->size();
56093fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                } else {
56103fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    info->mCodecData->setRange(0, size);
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5613078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5614ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5615078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
56165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5617ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
56185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5619078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5620d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5621ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5622ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5623d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5624ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5625ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5627078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5628349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5636054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5639054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5640054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5641054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5642054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5643054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5644054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5645054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5646054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5647054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
564815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5649d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
5650d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                status_t err2 = OK;
5651d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                switch (mCodec->mPortMode[kPortIndexInput]) {
5652d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetByteBuffer:
5653d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetANWBuffer:
5654d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModePresetSecureBuffer:
56553fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    {
56563fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
56573fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
56583fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    }
5659d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5660d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
5661d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModeDynamicNativeHandle:
5662d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
5663d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeHandleMetadata *vnhmd =
5664d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            (VideoNativeHandleMetadata*)info->mCodecData->base();
56653fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        sp<NativeHandle> handle = NativeHandle::create(
56663fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                                vnhmd->pHandle, false /* ownsHandle */);
56673fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
56683fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, handle, flags, timeUs, info->mFenceFd);
5669d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5670d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5671d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                case IOMX::kPortModeDynamicANWBuffer:
5672d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
5673d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                        VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
56743fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
56753fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                                vnmd->pBuffer, false /* keepOwnership */);
56763fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        err2 = mCodec->mOMXNode->emptyBuffer(
56773fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                            bufferID, graphicBuffer, flags, timeUs, info->mFenceFd);
5678d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    }
5679d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5680d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar#endif
5681d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                default:
5682d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
5683d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                            asString(mCodec->mPortMode[kPortIndexInput]),
5684d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                            info->mCodecData->size(),
5685d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                            sizeof(buffer_handle_t) * 8);
5686d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    err2 = ERROR_UNSUPPORTED;
5687d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                    break;
5688d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar                }
5689d34a8c4d9d7b197a9f5eb0d324273a6cde7e50a6Lajos Molnar
569015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
56920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
56930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
56940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5696fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                // Hold the reference while component is using the buffer.
5697fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                info->mData = buffer;
5698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
57005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
57015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
57020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
57030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
57045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
57065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
57075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
57090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
57100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5711dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5712dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
57133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5714dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5715dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5717ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5718349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5719349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
572015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
5721d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                status_t err2 = mCodec->mOMXNode->emptyBuffer(
57223fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                        bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd);
572315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
57240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
57250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
57260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
57270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5731dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5735625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5736777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5737777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5738777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5739625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5740777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5741625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5745f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
577815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
577915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5780609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
57815778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5782349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
57840806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5786d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5787d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5788d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5789d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5790d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5791d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5792d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5793d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5794d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5795d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5796d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5797d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5798d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5800d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
58030806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
58040806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
58050806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
58060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
58070806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
580815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
580915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
581015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
58110806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
58120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
581790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
581890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
581990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
582090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
582190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
582290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
582390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
582490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
582590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
582615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
582715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
582815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
582915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
583015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
583115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
583215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5841a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5842a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5843609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
58445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5845349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
58463fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                err = mCodec->fillBuffer(info);
58470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
58480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
58500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
58515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
58525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
585331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5854577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
58551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
5856ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim            sp<MediaCodecBuffer> buffer = info->mData;
5857577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5858b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5859697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                // pretend that output format has changed on the first frame (we used to do this)
5860697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
58611734c7d01c1567568ced29398b23abd601fd44cbLajos Molnar                    mCodec->onOutputFormatChanged(mCodec->mOutputFormat);
5862697aedf61d6180e72102068a969383018eedfa1eLajos Molnar                }
5863b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
5864b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
5865fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            } else if (rangeLength > 0 && mCodec->mNativeWindow != NULL) {
5866fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                // If potentially rendering onto a surface, always save key format data (crop &
5867fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                // data space) so that we can set it if and once the buffer is rendered.
5868fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
58695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5870ad60a0f6cd9012507f8086fe741236d12d280ef3Wonsik Kim            buffer->setFormat(mCodec->mOutputFormat);
5871b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5872d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang            if (mCodec->usingSecureBufferOnEncoderOutput()) {
5873054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
5874d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get());
5875d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                if (secureBuffer != NULL) {
58767c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
58773e328782f1e1061d08ea0c45b855cc418a2d9ea6Lajos Molnar                    // handle is only valid on 32-bit/mediaserver process
58787c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
58797c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
5880d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                    handle = (native_handle_t *)secureBuffer->getDestinationPointer();
58817c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5882054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
58837e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setPointer("handle", handle);
58847e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeOffset", rangeOffset);
58857e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->meta()->setInt32("rangeLength", rangeLength);
5886fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            } else if (buffer->base() == info->mCodecData->base()) {
58877e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                buffer->setRange(rangeOffset, rangeLength);
58885b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar            } else {
58895b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                info->mCodecData->setRange(rangeOffset, rangeLength);
58905b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                // in this case we know that mConverter is not null
58915b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
58927e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                        info->mCodecData, buffer);
58935b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                if (err != OK) {
58945b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58955b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                    return true;
58965b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar                }
5897308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
5898496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
589921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
5900496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
5901496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
5902496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
59035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
590421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59068b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
59077e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                mCodec->mSkipCutBuffer->submit(buffer);
59088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
59097e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            buffer->meta()->setInt64("timeUs", timeUs);
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5912d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5913609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
59147e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            notify->setObject("buffer", buffer);
5915fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            info->mData.clear();
59165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5918609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
59235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
59245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
59275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
59285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
5930d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
5931dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
5932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
5933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
5935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5939777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
59400806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
59410806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
59420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
59440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5946777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5948777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5949777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5957609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
59587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<RefBase> obj;
59597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer = nullptr;
59607e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    if (msg->findObject("buffer", &obj)) {
59617e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer = static_cast<MediaCodecBuffer *>(obj.get());
59627e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    }
5963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
59640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
59650806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
59660806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
59670806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
59680806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
59690806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
59700806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
59710806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5972fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    info->mData = buffer;
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5974577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
5975fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)
5976fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            && memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
5977fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar        mCodec->mLastNativeWindowCrop = crop;
5978777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5979777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5980577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
5981577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5982b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t dataSpace;
5983fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar    if (msg->findInt32("dataspace", &dataSpace)
5984fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar            && dataSpace != mCodec->mLastNativeWindowDataSpace) {
5985b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = native_window_set_buffers_data_space(
5986b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
5987fe73b95aaef79ad312d9dfdb6c8873bd50c6c19eLajos Molnar        mCodec->mLastNativeWindowDataSpace = dataSpace;
5988b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
5989b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5990b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
5992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
59936aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
59947e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            && buffer != NULL && buffer->size() != 0) {
59956fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
5996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
599890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
599990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
60007e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
600190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
600290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
600390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
600490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
600590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6006fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
6007fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
6008c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
60097e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            if (buffer->meta()->findInt64("timeUs", &timestampNs)) {
6010c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
6011fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
6012fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
6013fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
6014fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
60155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
6016fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
60170806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
6018fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
601915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
60200806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
602115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
602215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
60230806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
6024cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
6025cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
6026264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
6027251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6028cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
602915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
603015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
6031cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
6032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
60336fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
60347e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            (buffer == NULL || buffer->size() != 0)) {
603515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
603615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
60376fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
60386fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
6040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
6043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
6046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
6048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
6051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
6052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
6054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
6063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
6064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
6066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6068c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
6069609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
6070c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
607115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
60723fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    status_t err = mCodec->fillBuffer(info);
60733fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang                    if (err != OK) {
60740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
6076c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
6077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6081777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
6082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
60830806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
60840806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
60850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
60860806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6089777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
6090777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
6091777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
6092777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
6093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6098f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6102c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
6103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
6104ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6105ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
61061d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        if (mCodec->mOMXNode != NULL) {
61071d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang            sp<IBinder> binder = IInterface::asBinder(mCodec->mOMXNode);
61081d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang            binder->unlinkToDeath(mDeathNotifier);
61091d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        }
6110ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
6111ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
6112ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6113b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
6114ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
6115e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
6116ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
6117d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode.clear();
6118ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
6119d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
6120d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang    mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
61215b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[0].clear();
61225b4401b28990107bb797dc0d5f3904cf27417e98Lajos Molnar    mCodec->mConverter[1].clear();
6123ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
6124c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6125c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
6127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
6131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
61395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
61405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
61415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
61425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
61435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
61445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
6146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
615054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
615154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
6152c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6154349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang            notify->setInt32("what", keepComponentAllocated ?
6155349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                    CodecBase::kWhatStopCompleted : CodecBase::kWhatReleaseCompleted);
6156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6159c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
6163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6165d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
6167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6169c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
6170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
617230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
617330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
617430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
617530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
617630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
617730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
617830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
6179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6186f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
61925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
61935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
61955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
61965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6197d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode == NULL);
61985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
620048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
620148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
620248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
620348a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
6204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6208ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6209b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
62105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
6214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
62157791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
62165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6217b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6218b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6219b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6220afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
62215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
62225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
62235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
62245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
62255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
62265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
62275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6228b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
62295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
62305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6231b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6232e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
62335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
62341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
62351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6236d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
62371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6238201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
62391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
62401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6241b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6242b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6244da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6245078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6246078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
62471d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang        err = omx->allocateNode(componentName.c_str(), observer, &omxNode);
6248078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
62511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
62527a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
62537a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
62541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
62551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6256d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode = NULL;
62571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
62581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6259d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (omxNode == NULL) {
62605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
62619f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
62629f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
62635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
62649f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
62655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6266c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
626752e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6269c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
627123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
62721d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang    if (IInterface::asBinder(omxNode)->linkToDeath(mDeathNotifier) != OK) {
627323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // This was a local binder, if it dies so do we, we won't care
627423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // about any notifications in the afterlife.
627523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mDeathNotifier.clear();
627623858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
627723858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
627826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6279d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    notify->setInt32("generation", ++mCodec->mNodeGeneration);
6280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
628390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6285ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6286ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6287ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
62881713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
62890167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6290ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6291ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
629221b46588d022d0c22d7c7c08e919d7a9c5cd76e3Chong Zhang    omxNode->setQuirks(quirks);
6293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6294d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    mCodec->mOMXNode = omxNode;
6295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
62975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6298d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
62995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
63005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
63015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
63065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
63075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6316c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6317f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6318f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6319f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6320f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6321f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6322054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6323054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6324a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6325e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6326e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
63274e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
63286d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    mCodec->mGraphicBufferSource.clear();
6329054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6331c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6332c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6336c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
633854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6339f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6340f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6343c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6344c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
6345d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        (void)mCodec->mOMXNode->freeNode();
6346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6347c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6349c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
635054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
635154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
6352349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang        notify->setInt32("what", keepComponentAllocated ?
6353349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                CodecBase::kWhatStopCompleted : CodecBase::kWhatReleaseCompleted);
635454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
635554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
635654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6358c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6359c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6360c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6366c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6367c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6368c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
63707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
63717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
63727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
63737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
63747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
63757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
63767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
63778f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6378d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
63798f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6380d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6381d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6382d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6383d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6384c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6385c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6386c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6387c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6388c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6391c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6392c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6393c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6394c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6395c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6396c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
639754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6398c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6404c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6405c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6406c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6407d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
6409c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6411c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6412c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6414c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6416c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6417c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6418c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6420c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6421c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
64225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
64235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
64245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6425d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    CHECK(mCodec->mOMXNode != NULL);
64265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
64270806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
64285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
64290806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
64300806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
64310806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
64320806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
64330806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
64345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6435c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6436c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6437c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6438251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
64405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
64435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6444d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
6445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
6446e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
64475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
64485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
64515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
64525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6453d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6454addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (mCodec->mGraphicBufferSource == NULL) {
6455addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return BAD_VALUE;
6456addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6457addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6458addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    android_dataspace dataSpace;
6459addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err =
6460addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6461addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != OK) {
6462addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Failed to get default data space");
6463addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
6464addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6465addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
6466addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    err = statusFromBinderStatus(
6467addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace));
6468addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (err != OK) {
6469addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("[%s] Unable to configure for node (err %d)",
6470addf2cbb120346ae42e78fa739245a353db5edadChong Zhang              mCodec->mComponentName.c_str(), err);
6471addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        return err;
6472addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    }
6473a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6474d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
64756d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
64766d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setRepeatPreviousFrameDelayUs(
64776d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mRepeatFrameDelayUs));
6478a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6479a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6480a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6481a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
64826d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6483d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6484a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6485a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6486a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6487d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
64883604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        OMX_PARAM_U32TYPE maxPtsGapParams;
64893604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        InitOMXParams(&maxPtsGapParams);
64903604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        maxPtsGapParams.nPortIndex = kPortIndexInput;
64913604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        maxPtsGapParams.nU32 = (uint32_t) mCodec->mMaxPtsGapUs;
64923604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang
64933604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang        err = mCodec->mOMXNode->setParameter(
64943604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang                (OMX_INDEXTYPE)OMX_IndexParamMaxFrameDurationForBitrateControl,
64953604cb1a5548694393c7b7a87191eb517bebaa47Chong Zhang                &maxPtsGapParams, sizeof(maxPtsGapParams));
649694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
649794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
649894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
64996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6500d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
65012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
65022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
65032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6504d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
65056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65066d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setMaxFps(mCodec->mMaxFps));
650737b2b389139ed638831e49708c947863eef631efRonghua Wu
650837b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
650937b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
65106d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6511d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
651237b2b389139ed638831e49708c947863eef631efRonghua Wu        }
651337b2b389139ed638831e49708c947863eef631efRonghua Wu    }
651437b2b389139ed638831e49708c947863eef631efRonghua Wu
6515d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
65162c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
65176d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65186d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setTimeLapseConfig(
65196d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        mCodec->mTimePerFrameUs, mCodec->mTimePerCaptureUs));
65202c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
65212c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
65222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
65236d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mCodec->mComponentName.c_str(), err);
6524d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
65252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
65262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
652772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6528d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
65296d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65306d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setSuspend(true));
653172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
653272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
653372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
65346d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                  mCodec->mComponentName.c_str(), err);
6535d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
653694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
653794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
653894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6539c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6540d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    if (mCodec->mOMXNode->getParameter(
6541d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6542c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6543c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6544c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6545c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6546c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
65496d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (colorAspectsBuffer->size() != sizeof(ColorAspects)) {
65506d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
65516d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
65526d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
65536d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(
65546d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
65556d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                        *(ColorAspects *)colorAspectsBuffer->base())));
65566d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
6557b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6558b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6559b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6560b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6561b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6562b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6563d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6564d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6565d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6566d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6567d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6568d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6569d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6570d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6571d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
6572d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6573d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6574addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = mCodec->mOMX->createInputSurface(
6575addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            &bufferProducer, &mCodec->mGraphicBufferSource);
6576d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6577d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6578d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6579d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6580d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
65817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
6582addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        notify->setMessage("input-format", mCodec->mInputFormat);
6583addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        notify->setMessage("output-format", mCodec->mOutputFormat);
6584addf2cbb120346ae42e78fa739245a353db5edadChong Zhang
65857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
65867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
65877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
65887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
65897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
65907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
65917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
65927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
65937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
65947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
65957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
65967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
65977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
65988f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
6599d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
66008f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6601d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6602d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6603d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
6604d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6605d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6606d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6607d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6608addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    mCodec->mGraphicBufferSource = surface->getBufferSource();
6609d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6610addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = setupInputSurface();
6611b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6612b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6613addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        notify->setMessage("input-format", mCodec->mInputFormat);
6614addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        notify->setMessage("output-format", mCodec->mOutputFormat);
6615addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    } else {
6616d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6617d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6618d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
66198f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6620d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
6621d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
6622d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6623d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
6624d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6625d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
66275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
66285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6629d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandStateSet, OMX_StateIdle);
66300806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
66310806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
66320806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
66330806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
66340806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6639f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6643f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
66443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6646cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6647cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
664829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6649cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6650cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6651cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6652251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
665391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6654d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        mCodec->mOMXNode->sendCommand(
6655d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
6656c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6657c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6658c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6659c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6660c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6661c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6662c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
666391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6664cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6667f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
6675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6677f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
667972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
66876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
66886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
66896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
66906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
66916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
66926463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
66936463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
66946463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
66956463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
66966463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
66976463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
66986463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
66996463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
67006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
67016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
6702d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
67036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
67046463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
67056463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
67066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6712f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
67170806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
67180806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
67190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
67200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
67210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
67220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
67230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
67240806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
6727d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                err = mCodec->mOMXNode->sendCommand(
6728d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateExecuting);
67290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
67320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
67330806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
67340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
67350806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6747f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6751f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
67523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6755f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
675772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6764d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6765d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6766d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6767d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6768d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6769d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6770d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6771d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6772d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
6773d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6774d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6775d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
6776d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6777d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6778d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6779d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
67806507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
67816507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
67826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
67836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
67846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
67856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6791f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
67960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
67970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
67980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
67990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
68000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
68010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
68030806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6818f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6819349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6820349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6823f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6824ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6835054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
68394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
68404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6841054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
68450806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
68500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
68510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
68520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
68530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
68540806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
68550806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
68610806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
68620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
68630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
68640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
68650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68680806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6869349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
687015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
68713fd200feb657c157125e45e30c2a7262e3c0244dChong Zhang        status_t err = mCodec->fillBuffer(info);
68720806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
68730806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
68740806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
68750806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
68770806340688c937e7b78c2d89db3809274130df4eLajos Molnar
68780806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
68790806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
68800806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6884c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6885054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6886054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6890f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6891349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
68920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6893349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6894349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6895349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
68983cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6899777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6900777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6901777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
69033cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
69043cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
69053cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
69063cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
69073cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
69083cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6909349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6910349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6913f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
69143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
691690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
6918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6920f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6926c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6927c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6928c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6929c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6930c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
693154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6932c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6933c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6934349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6935349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6936d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(
6937d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_CommandStateSet, OMX_StateIdle);
69380806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
69390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
69400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
69420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
69430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
69450806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
69537a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
6954ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
6955d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
6956d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6957d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
6958d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6959d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
6960d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6961349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6962349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6963d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = mCodec->mOMXNode->sendCommand(OMX_CommandFlush, OMX_ALL);
69640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
69650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
69660806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
69670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
69680806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
6975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
6977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6982496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
6983496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
6984496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
6985496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
6986496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
6987496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
6988496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6989496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
6990496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
6991496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
6992496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6993a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
6994a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
6995a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
6996a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
6997a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6998a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
6999a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7000a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
7001a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
7002a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
7003a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
7004a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
7005a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7006a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
7007a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
7008a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7009a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
70107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
70117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
70126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
70137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
70147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
70157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
70167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
70174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
7018054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
70194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
70204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
70214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
7022054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
70234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
7024054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
70254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
70264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
70274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
70284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
70294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
7030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7038a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
7039a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
7040530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
7041a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
7042a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
7043a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
7044a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
7045a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7046d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mOMXNode->setConfig(
7047a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
7048a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
7049a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
7050a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7051a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
7052a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
7053a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
7054a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
7055a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
7056a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
7057a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
7058a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
705961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    int64_t timeOffsetUs;
706061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    if (params->findInt64("time-offset-us", &timeOffsetUs)) {
70616d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
70626d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set input buffer time offset without surface",
70636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
70646d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
70656d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
70666d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
70676d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
70686d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setTimeOffsetUs(timeOffsetUs));
706961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
707061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        if (err != OK) {
707161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            ALOGE("[%s] Unable to set input buffer time offset (err %d)",
707261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                mComponentName.c_str(),
707361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                err);
707461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            return err;
707561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
707661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    }
707761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
707872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
707972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
70806d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
70816d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set start time without surface",
70826d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
70836d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
70846d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
70856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang
70866d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
70876d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setStartTimeUs(skipFramesBeforeUs));
708872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
708972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
709072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
709172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
709272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
709372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
709472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7095e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
7096e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
70976d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mGraphicBufferSource == NULL) {
70986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            ALOGE("[%s] Invalid to set suspend without surface",
70996d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                    mComponentName.c_str());
71006d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            return INVALID_OPERATION;
71016d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        }
7102e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
71036d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        status_t err = statusFromBinderStatus(
71046d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang                mGraphicBufferSource->setSuspend(dropInputFrames != 0));
7105b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7106b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7107b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
7108b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7109b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7110b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
7111b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7112b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
7113b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
7114b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
7115b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
7116b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
7117b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
7118b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
7119b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
7120e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
7121e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
71228db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
71238db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
71248db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
71258db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
71268db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
71278db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
71288db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
71298db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
71308db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
7131870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
7132870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
7133870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
7134870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
7135870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
7136870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
7137870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
7138870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
7139870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
7140870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
7141870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
71420f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    status_t err = configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
71430f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    if (err != OK) {
71440f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar        err = OK; // ignore failure
71450f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    }
71460f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar
71470f7442ddb82d5ceba2e0c081dc3d62996f1570a0Lajos Molnar    return err;
7148a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
7149a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
71506507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
71516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
7152d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
71536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
71546d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    status_t err = INVALID_OPERATION;
71556d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    if (mGraphicBufferSource != NULL) {
71566d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        err = statusFromBinderStatus(mGraphicBufferSource->signalEndOfInputStream());
71576d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang    }
71586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
71596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
71606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
71616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
71626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
71636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
716490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
716590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
716690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
716790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
716890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7169f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
7170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
7173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
7175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7176b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
7177b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
717831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
7179054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
7180d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                CHECK_EQ(mCodec->mOMXNode->sendCommand(
7181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
7182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
7183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7184349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
7185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
7187b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
7188b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
7189ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
7190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
7191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7208f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7213f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7224f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7231349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7232e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7234349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
72353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7236349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7237349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7251f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
72523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
725690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
725790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
725890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
725990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
726090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
726190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7262f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
72680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
72690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
72700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
72710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
72760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
72770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
72780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
72790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
72800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
72810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
72820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
7285d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    err = mCodec->mOMXNode->sendCommand(
7286d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                            OMX_CommandPortEnable, kPortIndexOutput);
72870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
72900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
72910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
72920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
72930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7294cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
72950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7296251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7297d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7298755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7299755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7300755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7301755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7302755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7303755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7304755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7305755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7306cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7310777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7311777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7312777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7313777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7317349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7318349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7319349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7320349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7336f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
73375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
73385778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7341f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
73490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7355349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang            mCodec->deferMessage(msg);
7356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7368f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
73693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
737031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
73715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7372b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7375f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
73800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
73810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
73820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
73830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
73840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
73850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
73870806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
73895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
73905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7396349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7397349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7398349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7400349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7401349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
74070af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7408f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
74095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
7410d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        status_t err = mCodec->mOMXNode->sendCommand(
7411d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                OMX_CommandStateSet, OMX_StateLoaded);
74120806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
74130806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
74140806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
74150806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
74160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
74170806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
74180806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74200167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
74210167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7422bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7423bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7424bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7425bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7426b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7427bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7428bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
74290806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
74300806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
74310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
74320806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
74330806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7438f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7445f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7454f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7458f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7464349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang            mCodec->deferMessage(msg);
7465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
74730806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7485f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
74863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7489f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
74940806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
74950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
74960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
74970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
74980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
74990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
75000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
75010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7515f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7519f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
75203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7525f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7550f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
7551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7552ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
7553ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
7554d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
75580806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
75590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
75600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
75610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
75620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
75630806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
7566777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
7567777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
7568777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
7569777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
7570777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
7572e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
75730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
7574e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
7575e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
7576777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
7577777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
7578777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
7579777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
7580777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
7581777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7582777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
7585777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
7586777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
7587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7592349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7593349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
75941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
7595349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
7596d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            msg->setInt32("generation", mCodec->mNodeGeneration);
7597349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
7598349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
7599349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
7600349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
76013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
7602349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
7603349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7604349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
7605349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7606349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7607349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7608349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
7614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7616f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
7617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7622f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
7623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7628f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
7629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
7630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
7631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
76327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
76337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
76347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
76357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
763690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
763790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
7639d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
7640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
7641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
7643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
7644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7645dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
7646dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
7647f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
7648f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
7649f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
7650f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
7651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
7652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
76565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
76575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
76585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
76591ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim    const char *role = GetComponentRole(isEncoder, mime.c_str());
76605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
76615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
76625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
76655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = client.connect();
76665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
76715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
7672d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    sp<IOMXNode> omxNode;
76735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76741d2e9cfbe3f2db16ecafd2adafb4c60d7235a2ceChong Zhang    err = omx->allocateNode(name.c_str(), observer, &omxNode);
76755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
76765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
76775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7680d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    err = SetComponentRole(omxNode, role);
76815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
7682d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        omxNode->freeNode();
76835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
76845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
76855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
76885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
76895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
76915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
76925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
76935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
76945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76956e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
76966e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
7697d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7698d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoProfileLevelQuerySupported,
76995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
77005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
77015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
77025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
77035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
77046e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
77056e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
77066e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
77076e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
77086e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
77096e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
77105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
77135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
77145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
77155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
77165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
771736e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
77185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
77196e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
77206e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
7721d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7722d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    OMX_IndexParamVideoPortFormat,
77235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
77245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
77255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
77265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
77275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
77291ad5b240bfd49aa918092dbdc18c1a24c5e6c3a4Wonsik Kim            if (IsFlexibleColorFormat(
7730d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    omxNode, portFormat.eColorFormat, false /* usingNativeWindow */,
77315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
77325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
77335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
77345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
77355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
77365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
77375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
77385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
77395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
77405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
77415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
77425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
77435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
77445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
77455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
77466e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
77476e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
77486e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
77496e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
77506e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
77516e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
77525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
77545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
77555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
77565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
77575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
77586e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
77596e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
7760d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang            status_t err = omxNode->getParameter(
7761d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                    (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
77625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
77635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
77645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
77655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
77665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
77675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
77686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
77696e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
77706e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
77716e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
77726e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
77736e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
77745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
77775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
77785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
77795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
77805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
77845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
7785d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->configureVideoTunnelMode(
7786d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
77875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
77885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
77895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
7790d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang        } else if (omxNode->setPortMode(
7791d02c08671d666e12a94bcadd943787a9ab2ceea8Chong Zhang                kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
7792d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                omxNode->prepareForAdaptivePlayback(
7793d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                kPortIndexOutput, OMX_TRUE,
77945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
77955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
77965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
77975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
77985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
77995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
78005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
78015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
78025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
78035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
7804d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang        if (omxNode->getConfig(
7805d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang                (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
78065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
78075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
78085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
78095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
78105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
78115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
7812d59b97223424a3974d2ac31cff998d02eecf2eedChong Zhang    omxNode->freeNode();
78135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
78145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
78155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
78165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7817a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
7818a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
7819a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
7820a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
7821a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
7822a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
7823a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
7824a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7825a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
7826a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7827a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7828a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7829a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
7830a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7831a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7832a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7833a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7834a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
7835a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7836a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7837a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
7838a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
7839a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7840a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
7841a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7842a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7843a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7844a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
7845a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
7846a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7847a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
7848a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7849a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7850a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7851a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7852a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7853a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7854a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7855a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
7856a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7857a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7858a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7859a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7860a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7861a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7862a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
7863a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7864a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
7865a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7866a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7867a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7868a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7869a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7870a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7871a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
7872a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
7873a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7874a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
7875a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
7876a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
7877a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7878a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
7879a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
7880a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
7882