ACodec.cpp revision 78bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1b
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#ifdef __LP64__
21f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
22f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung#endif
23f87e30fe71752dc431d8e8d5682c38271c03265aAndy Hung
24609b815a3131d22da38b2f452faa9f89daad4039Andy Hung#include <inttypes.h>
256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
271de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar#include <gui/Surface.h>
281de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
37a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
4090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar#include <media/stagefright/MediaCodec.h>
41afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
44d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
45b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
52777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
5573dd808754c641fe798273d356ee38368715fa7bLajos Molnar#include "omx/OMXUtils.h"
56496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
57f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
596e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnarenum {
606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar};
626e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
99251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
100251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
101251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
102251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
103251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
10526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
10626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
10726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
108984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    virtual ~MessageList() {
109984a54322f7c70bc75e862d91bdd975814872affLajos Molnar    }
11026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
11126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
11226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
11326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
11426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
11526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
11626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
12526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
126984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        if (messages.empty()) {
127984a54322f7c70bc75e862d91bdd975814872affLajos Molnar            return;
128984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        }
129984a54322f7c70bc75e862d91bdd975814872affLajos Molnar
130984a54322f7c70bc75e862d91bdd975814872affLajos Molnar        sp<AMessage> notify = mNotify->dup();
13126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        bool first = true;
13226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
13326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
13426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
13526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
13626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            if (first) {
13726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                notify->setInt32("node", omx_msg.node);
138984a54322f7c70bc75e862d91bdd975814872affLajos Molnar                first = false;
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
14226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
14326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
14426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
14526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
14626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
14726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
14826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
14926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
15026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
15326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
15426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
15526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
15626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
15726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
16226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
16326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
16426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
16526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
16626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
16726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
16826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
16926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
17126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
17226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
17326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
17426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
17526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
17726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
17826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
18190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
18290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
18390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
18490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
18590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
18690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
18790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
18890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
18926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
19026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
19126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
19226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
19326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
19426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
19526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
19626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
23426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
23826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
23926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
24026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
24126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
24226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
24315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
24915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
25015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
25390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
261ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
262ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
263ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
264ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
265ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
266ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
267ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
268ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
269ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
270ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
271ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
272ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
273ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
274ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
275ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
276ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
277ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
278ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
291ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
300c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
301c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3098f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
313d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
314d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
316c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
317c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
318c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
319c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
354054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
362349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
363349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
37090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
373349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
374349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
38990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
45715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
45815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
45915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
46015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
46115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
46215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
46315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
46415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
46515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
46615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
46715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
46815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
46915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
47015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
47115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
47215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
47315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
47415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
47515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
47615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
47715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
47815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
47915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
48115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
48215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
48315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
48415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
48715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
488f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
489afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
490609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
491b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar      mUsingNativeWindow(false),
492e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar      mNativeWindowUsageBits(0),
4938db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
494c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
495346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang      mFatalError(false),
4969806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
49754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4989806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4999806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
500e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
5019806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
502054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
503054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
504054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mInputMetadataType(kMetadataBufferTypeInvalid),
505054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mOutputMetadataType(kMetadataBufferTypeInvalid),
506011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
507054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
50894ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
51037b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
5112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
512609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
513ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
5148338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mTunneled(false),
5158338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar      mDescribeColorAspectsIndex((OMX_INDEXTYPE)0) {
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
517c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
530dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
535f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
538f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
542f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
548a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
550a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
551a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
552a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
553a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5545778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5561d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5605778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
5711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
5721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
5741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
5751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
5771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
5781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
5801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
5817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5838f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
584d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
5858f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
586d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
587d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
588d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
589d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
5911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
5927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5945778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
5951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
598f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
5997a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
6001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
603f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
607c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
61130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
61230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
61430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
617496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
619496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
620496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
626054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
628054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
629054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6304dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
643e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // cannot switch from bytebuffers to surface
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
662e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    int usageBits = 0;
663e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow, &usageBits);
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
668f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    int ignoredFlags = kVideoGrallocUsage;
669e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    // New output surface is not allowed to add new usage flag except ignored ones.
670e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    if ((usageBits & ~(mNativeWindowUsageBits | ignoredFlags)) != 0) {
671e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ALOGW("cannot change usage from %#x to %#x", mNativeWindowUsageBits, usageBits);
672e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        return BAD_VALUE;
673e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    }
674e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
6771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
6781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
6791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
6801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
6811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
6831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
6841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
6931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
6941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
7001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
7011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
7021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
704dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
705dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
706dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
712054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
713011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
730054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
73215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
73615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
73715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
7471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
7481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
750484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
751484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
752484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
753484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
754484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
756e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mNativeWindowUsageBits = usageBits;
7571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
768054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()) {
769054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
782054219874873b41f1c815552987c10465c34ba2bLajos Molnar            MetadataBufferType type =
783054219874873b41f1c815552987c10465c34ba2bLajos Molnar                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
784054219874873b41f1c815552987c10465c34ba2bLajos Molnar            int32_t bufSize = def.nBufferSize;
785054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (type == kMetadataBufferTypeGrallocSource) {
786054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoGrallocMetadata);
787054219874873b41f1c815552987c10465c34ba2bLajos Molnar            } else if (type == kMetadataBufferTypeANWBuffer) {
788054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
789054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
790054219874873b41f1c815552987c10465c34ba2bLajos Molnar
791054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // If using gralloc or native source input metadata buffers, allocate largest
792054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // metadata size as we prefer to generate native source metadata, but component
7935fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // may require gralloc source. For camera source, allocate at least enough
7945fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            // size for native metadata buffers.
795054219874873b41f1c815552987c10465c34ba2bLajos Molnar            int32_t allottedSize = bufSize;
7965fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) {
797054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
7985fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar            } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
7995fb8b2987ab96ad65dc4b046616607ece16d6fb3Lajos Molnar                bufSize = max(bufSize, (int32_t)sizeof(VideoNativeMetadata));
800054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
801054219874873b41f1c815552987c10465c34ba2bLajos Molnar
80228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignment = MemoryDealer::getAllocationAlignment();
80328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
804054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port",
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
806054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
80928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            if (bufSize == 0 || bufSize > kMaxCodecBufferSize) {
81028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                ALOGE("b/22885421");
81128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar                return NO_MEMORY;
81228edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            }
81328edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
81428edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            // don't modify bufSize as OMX may not expect it to increase after negotiation
81528edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t alignedSize = align(bufSize, alignment);
81628edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            if (def.nBufferCountActual > SIZE_MAX / alignedSize) {
81734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                ALOGE("b/22885421");
81834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen                return NO_MEMORY;
81934e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            }
82028edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar
82128edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar            size_t totalSize = def.nBufferCountActual * alignedSize;
8225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
825054219874873b41f1c815552987c10465c34ba2bLajos Molnar                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
8265581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
827777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
828777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
831ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
83215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
83390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
834a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                info.mNativeHandle = NULL;
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
836afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
837afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
838b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        ? kRequiresAllocateBufferOnInputPorts
839b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                        : kRequiresAllocateBufferOnOutputPorts;
8401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
841e33d922fd86699c664a15f09e6d8b2e422736a40Lajos Molnar                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
842ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
843ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
844a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    void *ptr = NULL;
845a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    native_handle_t *native_handle = NULL;
846a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    err = mOMX->allocateSecureBuffer(
847054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, bufSize, &info.mBufferID,
848a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                            &ptr, &native_handle);
849a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
850a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY: this representation is unorthodox, but ACodec requires
851a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // an ABuffer with a proper size to validate range offsets and lengths.
852a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // Since mData is never referenced for secure input, it is used to store
853a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // either the pointer to the secure buffer, or the opaque handle as on
854a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // some devices ptr is actually an opaque handle, not a pointer.
855a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
856a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // TRICKY2: use native handle as the base of the ABuffer if received one,
857a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    // because Widevine source only receives these base addresses.
858a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    info.mData = new ABuffer(ptr != NULL ? ptr : (void *)native_handle, bufSize);
859a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    info.mNativeHandle = NativeHandle::create(native_handle, true /* ownsHandle */);
860ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
862054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
864054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
865ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
866ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
867ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
868054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    info.mData = new ABuffer(mem->pointer(), bufSize);
869054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (type == kMetadataBufferTypeANWBuffer) {
870054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
871054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
87286b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu                    info.mMemRef = mem;
8735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8741065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
8755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
8761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
8771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
885d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
888eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
889eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
890eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
8915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
892eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
893a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        desc->addBuffer(info.mBufferID, info.mData, info.mNativeHandle, info.mMemRef);
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
896eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
902e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(
903e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */) {
9041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
9091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
9121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
9161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
9171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
9181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
9191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
9201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
9211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
9231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
9251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
9261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
928f42917964a76720932b23e67a05d034cd0cf346bChong Zhang    usage |= kVideoGrallocUsage;
929e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    *finalUsage = usage;
930b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
9311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
9321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
9331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
9341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
9351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
9361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
9371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
9381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
9391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
9401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
9421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
9431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
9441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
9491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
952e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get(), &mNativeWindowUsageBits);
9531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
955e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar        mNativeWindowUsageBits = 0;
9561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
959ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
960ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
961ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
962ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
963ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
964ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
965ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
966ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
967ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
968ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
969ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
970ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
971ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
972ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
973ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
975258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
976258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
978258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
979258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
98029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
981258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
982258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
983258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
984258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
985e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
986e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
9871faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
9881faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
989e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
990e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
991e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
992e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
993e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
994e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
995e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
9961faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
9971faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
998e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
999e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
1000258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
1001258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
1002258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1003258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1004e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
1005e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
1006e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
1007e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
1008e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
1009609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
1010e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
1011e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
1012e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
1013258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
1014258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
1015258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
1016258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
102129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1026054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
1027054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
1028054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1029054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1030054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1031054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
1032054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1033054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1034054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1035054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1036054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1037e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1038054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1039054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
10403298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
10413298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
10423298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10433298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1044609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1046054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1049054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
10508ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
105115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
105215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
105429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
105974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
106074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
106115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
106215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
106390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1064054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
106574006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
106674006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
106774006804065941841883c4b46ee785070164023fJamie Gennis
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1072609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
107374006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
107874006804065941841883c4b46ee785070164023fJamie Gennis
1079609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
1088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
1089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
109174006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1093054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1094054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1095054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
11003175d2babfcdcb64f41309157e0436d00375ae4bWei Jia        if (info->mStatus == BufferInfo::OWNED_BY_US) {
11013175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            status_t error = cancelBufferToNativeWindow(info);
11023175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (err == 0) {
11033175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                err = error;
11043175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            }
11053fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1108054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
11093298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
11103298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
11113298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
11123298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1116054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1117054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1122e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1123054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1124e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1125e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1126e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1127054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1128054219874873b41f1c815552987c10465c34ba2bLajos Molnar            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
112928edbba6aa6c1a9bbea76da2f5cc3cd73af8eb4cLajos Molnar    size_t totalSize = bufferCount * align(bufSize, MemoryDealer::getAllocationAlignment());
1130e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1131e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1132e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
1133e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1134e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1135e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
113615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
113790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1138e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1139e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1140e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1141054219874873b41f1c815552987c10465c34ba2bLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
11425581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
1143777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
1144777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1145054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1146054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1147054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1148e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
1149e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1150e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
1151e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        err = mOMX->useBuffer(
1152cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
115386b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu        info.mMemRef = mem;
1154e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1155e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1156e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1157e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1158e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1159e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1160011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1161e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1162011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1163011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1164011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1165011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1166011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1167011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1168011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1169011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1170011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1171e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1172e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1173011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
117415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd;
117515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1176011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1177011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1178011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1179011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1180011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1181011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1182e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            mOMX->updateGraphicBufferInMeta(
1183e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1184e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
118515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1186e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1187011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1188011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1189011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1190011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
11913175d2babfcdcb64f41309157e0436d00375ae4bWei Jia            if (info->mStatus == BufferInfo::OWNED_BY_US) {
11923175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                status_t error = cancelBufferToNativeWindow(info);
11933175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                if (err == OK) {
11943175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                    err = error;
11953175d2babfcdcb64f41309157e0436d00375ae4bWei Jia                }
1196011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1197011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1198011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1199011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1200011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1201011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1202011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1203054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1204054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1205054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1206054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1207054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1208054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1209054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1210054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1211054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1212054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
12130806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1214054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
12150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1216054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1217609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1218054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1219054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1220054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
122115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
122215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
122315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1224777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1225777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1226777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1227054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1228777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1229054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
123115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
123215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
123315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
123415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
123515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
123615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
123715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
123815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
123915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
124015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
12410806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
12420806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
12430806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
12440806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
12450806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
12460806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
12470806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
12480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
12490806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
12500806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
12510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
12520806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
12530806340688c937e7b78c2d89db3809274130df4eLajos Molnar
12540806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
12550806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
12560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
12570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
12580806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
12590806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
12600806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
12610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
12620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
12630806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
12640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
12650806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
12660806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1270609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
127315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
127515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
127615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12783fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
12793fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
12800806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12833fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
128790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
128890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
128990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
129090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
129190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
129290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
129390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
129490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
129590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
129690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
129790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
129890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
129990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
130090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
130190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
130290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
130390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
130490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = mNotify->dup();
130590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
130690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
130790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
130890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
130990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
131090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
131190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
1312604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        ssize_t index = it->getIndex();
1313604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        if (index >= 0 && (size_t)index < mBuffers[kPortIndexOutput].size()) {
1314604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(index).mRenderInfo = NULL;
1315604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        } else if (index >= 0) {
1316604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            // THIS SHOULD NEVER HAPPEN
1317604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar            ALOGE("invalid index %zd in %zu", index, mBuffers[kPortIndexOutput].size());
131890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
131990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
132090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
132190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
132290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->post();
132390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
132490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
132590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1326f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
13278ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1328054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1329ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1330ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1331ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1332ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1333ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1334ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1335ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1336346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    if (mFatalError) {
1337346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        ALOGW("not dequeuing from native window due to fatal error");
1338346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang        return NULL;
1339346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    }
1340346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
134115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1342dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
134315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
134415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
134515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1346dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1347dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1349dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1350b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1351b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker            i--;
1352dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1353dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1354dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
135590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1356dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1357dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1358dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1359dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1360dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1361dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1362dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1363dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1364dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1365dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1366dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1367dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
136890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1369dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1370dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
137115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
137290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1373dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1374dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1375dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1377dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1378dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1379dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1380dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1381dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1382054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1383dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1384dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1385dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1386dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1387dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1388dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1390dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1391054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1392dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1393dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1394b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1395b92add32c22656dedfb82d26ccc168c43c92b8ebChad Brubaker        i--;
1396dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1397dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1398054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1399054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1400054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1401054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1402054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1403054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1404054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1405054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1406054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14070806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
14080806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
14090806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
14100806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1411054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1412054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
14130806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
14140806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
14150806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
141615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
141790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
141890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1419d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
14200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    mOMX->updateGraphicBufferInMeta(
14210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
14220806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mBufferID);
1423054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1424054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1425054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata *grallocMeta =
1426054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1427054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1428054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1429054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14307c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)grallocMeta->pHandle,
1431054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1432054219874873b41f1c815552987c10465c34ba2bLajos Molnar    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1433054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata *nativeMeta =
1434054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1435054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1436054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1437054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
14387c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                (void *)(uintptr_t)nativeMeta->pBuffer,
1439054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1440054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
14430806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1447777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1448938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[portIndex].size(); i > 0;) {
1449938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1450777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1451777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1452777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1453777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1458777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1461349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1462777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1463938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich    for (size_t i = mBuffers[kPortIndexOutput].size(); i > 0;) {
1464938e2b34b16c3c1fd29c753eeb53ee95a2b2e2b3Nick Kralevich        i--;
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14682ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
14692ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
14702ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
14712ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1472777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1473777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1474777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1475777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1479777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
14840806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
148715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    MetadataBufferType type =
148815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
148915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
149015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
149115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
149215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
149315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
149415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
149515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
149615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
149715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
14980806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
14990806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
15000806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
15010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
15020806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
15030806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15050806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
15060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
15070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
15080806340688c937e7b78c2d89db3809274130df4eLajos Molnar
15090806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
15100806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
15110806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
15120806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
151615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
151715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
151815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
1519604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    if (portIndex == kPortIndexOutput) {
1520604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        mRenderTracker.untrackFrame(info->mRenderInfo, i);
1521604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar        info->mRenderInfo = NULL;
1522604bb9ea6e9bec763ae231330066ecffa90a2786Lajos Molnar    }
152390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1524777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1526777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1529f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
15300806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1542777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
15485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    const char *role = getComponentRole(isEncoder, mime);
15495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
15505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
15515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
15525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = setComponentRole(mOMX, mNode, role);
15535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
15545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        ALOGW("[%s] Failed to set standard component role '%s'.",
15555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar             mComponentName.c_str(), role);
15565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
15575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return err;
15585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
15595b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
15605b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
15615b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarconst char *ACodec::getComponentRole(
15625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        bool isEncoder, const char *mime) {
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
15722944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
15732944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
15742944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
15752944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1584bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1585bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1586c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1587c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1588c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1589c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
15922472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
15932472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
159894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
159994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
160094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
160194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1602ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1603ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
1604a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu        { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION,
1605a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu            "video_decoder.dolby-vision", "video_encoder.dolby-vision" },
16062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
16072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1608ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1609ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1610774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1611774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
161297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
161397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
16148a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
16158a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
16295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NULL;
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return isEncoder ? kMimeToRole[i].encoderRole
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
16345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
16375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::setComponentRole(
16385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node, const char *role) {
16395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMX_PARAM_COMPONENTROLETYPE roleParams;
16405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    InitOMXParams(&roleParams);
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    strncpy((char *)roleParams.cRole,
16435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            role, OMX_MAX_STRINGNAME_SIZE - 1);
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return omx->setParameter(
16485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            node, OMX_IndexParamStandardComponentRole,
16495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            &roleParams, sizeof(roleParams));
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1659b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> inputFormat = new AMessage;
1660b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> outputFormat = new AMessage;
1661b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mConfigFormat = msg;
1662e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1665054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mInputMetadataType = kMetadataBufferTypeInvalid;
1666054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mOutputMetadataType = kMetadataBufferTypeInvalid;
16678db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
16752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
16762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
16772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1681d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1682d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1683d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1684d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1685054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1686d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1687054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1688308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1690054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
1691054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1692054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // For this specific case we could be using camera source even if storeMetaDataInBuffers
1693054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
1694054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
1695054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mInputMetadataType = kMetadataBufferTypeCameraSource;
1696054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1697c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
1698c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        uint32_t usageBits;
1699c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mOMX->getParameter(
1700c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
1701c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                &usageBits, sizeof(usageBits)) == OK) {
1702c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            inputFormat->setInt32(
1703c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                    "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
1704c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
1705054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1706d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1707308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
17083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
17093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
17103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
17113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
17123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
17133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
17143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
17153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
17163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
17183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
17193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
17203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
17213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
17233a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
17243a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17253a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17263a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
17273a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
17283a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
17293a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
17303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
17313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
17323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
17333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1734308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1735308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1736308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1737308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
17388db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1739308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1740308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1741308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1742308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1743308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1744054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1745308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1746308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1747308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1748308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1749a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1750a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1751a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1752a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1753a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1754a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
175594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
175694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
17572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
17582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
17592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
176037b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
176137b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
176237b2b389139ed638831e49708c947863eef631efRonghua Wu        }
176337b2b389139ed638831e49708c947863eef631efRonghua Wu
17642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
17652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
176694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
176772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
176872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
176972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
177072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
177172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
177272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1773308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1774308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
17753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
17770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
17783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1779b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mUsingNativeWindow = haveNativeWindow;
1780011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1781e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1782e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
17831713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
17841713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
17851713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
17861713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
17871713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
17881713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
17891713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
17901713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
17911713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
17921713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1793a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
1794a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        if (mFlags & kFlagIsSecure) {
1795a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            // use native_handles for secure input buffers
1796a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = mOMX->enableNativeBuffers(
1797a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                    mNode, kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
1798a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            ALOGI_IF(err != OK, "falling back to non-native_handles");
1799a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar            err = OK; // ignore error for now
1800a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        }
1801e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
18023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
18031de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
18041de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
18055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18066597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
18076597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
18086597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
18096597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
18106597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
18116597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
18126597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
18136597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
18146597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
18156597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
18166597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
18176597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
18186597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
18196597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
18206597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
18216597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
18226597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
18236597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
18245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
18255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
18265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
18275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1828ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
18295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
183097827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
183197827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
18325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
18335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
18355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
183697827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
18375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
18385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1839fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1840fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1841d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1842d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1843d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1844d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1845d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1846d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1847d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1848d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1849d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
18503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
18513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1852d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1853d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1854d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1855d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1856d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1857d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
18585a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1859ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1860ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1861ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
18623fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
18633fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
18643fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
18653fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
18663fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
18673fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
18683fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
18693fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
18703fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
18715a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
18725a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
1873054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
18745a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
18755a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1876fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1877e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
18785a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
18795a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
18805a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
18815a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18825a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
18835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
18845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
18855a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
18865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
18875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18885a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
18895a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
18905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
18915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
18925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
18935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
18945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
18955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
18965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
18975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
18985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
18995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
19015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
19025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
19035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
19045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
19055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
19065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
19085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
19095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
19105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
19115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
19125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
19135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
19145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
19155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
19165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
19175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
19185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1919e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
19205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
19215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
19225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
19235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
19245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
1925054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
1926011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1927011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1928011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
19295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1930fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
19310167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
19325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
19335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
19345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
19355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
19365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
19370167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1938e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1939e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1940e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1941e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1942e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1943e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1944e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1946054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1947308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
19483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
19493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
19503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
19513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
19523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
19533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19543a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
1956b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoEncoder(mime, msg, outputFormat, inputFormat);
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1958b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
19623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
19633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
19661de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
19673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19683a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19693a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
19703a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1971777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1972777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1973777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1974777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
19753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
19773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
19783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
19793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
19803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1981777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1982777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1983777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1984777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19853a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
19863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1987777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1988777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1989777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1990777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
19923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
19933a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
19943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
19953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
19963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
19973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
19983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
19993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
2000e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar                    mNativeWindowUsageBits = 0;
20013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
20023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
2003054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (storingMetadataInDecodedBuffers()) {
2004054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        err = mOMX->storeMetaDataInBuffers(
2005054219874873b41f1c815552987c10465c34ba2bLajos Molnar                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
2006054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
20073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
20083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
20093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
20103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
2012a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                        err = mOMX->enableNativeBuffers(
2013a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                                mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
20143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
20163a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
20173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
20183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
2019b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        err = setupVideoDecoder(
2020b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mime, msg, haveNativeWindow, usingSwRenderer, outputFormat);
20213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
20223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
20233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
20243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
20253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
20263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
20273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
20283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
202942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
203042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
203142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
203242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
203342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
203442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
203542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
203642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
203742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
203842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
203942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
204042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
204142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2048aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
2049b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
20508045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
20512965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
20528045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
2053ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
2054ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
2055ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
2056aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
2057aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
2058aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
2059b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
2060b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
2061b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
2062ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20638045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
20648045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
20658045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20662965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
20672965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
20682965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
20692965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
20708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
20718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
20738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
20758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
20778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
20798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
20818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
20838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
20858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
20878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
20888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
20898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
20908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2091ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
20924471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
20932965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
20942965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2096729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2098729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2100729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2101729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2102729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2103729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2104729de186450f78c099637e1fce743fe531862c52Andreas Huber
2105729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
210917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
211017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
211117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
211217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
211317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2116ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
21172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
21182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
21192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
21202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
21212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
21222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
21232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2124516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2125cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2126cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2127516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2128cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
21292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2130516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2131516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2132516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
21342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2135516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2136516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2137516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
21382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
21392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
21402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2141516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2142516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
21432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2144ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2145ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2146ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2147ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2148ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2149ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2150ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
2151ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2152ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
215397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
215497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
215597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
215697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
215797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
215897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
215997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
216097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
216197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
21628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
21638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
21648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
21658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
21668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
21678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
21688a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
21698a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
21708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2172729de186450f78c099637e1fce743fe531862c52Andreas Huber
21734471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
21744471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
21754471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
21764471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
21778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
21788b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
21798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
21809806555d3930be43e11106281dee354820ac1c88Andreas Huber
21818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
21828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
21838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
21848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
21859806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
21869806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
21879806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
21889806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
21899806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
21909806555d3930be43e11106281dee354820ac1c88Andreas Huber
2191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21988b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
21998b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
22008b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
22018b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22028b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2203ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2204ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2205ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2206ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2207ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2208ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2209ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2210ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2211ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2212ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
22134e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
2214b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // trigger a kWhatOutputFormatChanged msg on first buffer
2215b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat.clear();
22164e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2217777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2218777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2219777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2220777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2221777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2222777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2223777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2224777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22288b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
22298b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
22308b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
22318b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22328b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
22338b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
22348b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
22358b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
22368b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
22378b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
22388b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
22398b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
22408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
22418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
22428b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
22438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2244ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2245ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2246ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2247ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2248ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2249ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2250ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2251ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2252ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2253ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2254ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2255ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2256ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2257ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2258ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2259ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2260ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2261ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2262ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2263ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
2264ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2265ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2266ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2267ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2268ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2269ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2270ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2271ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2272870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::getIntraRefreshPeriod(uint32_t *intraRefreshPeriod) {
2273870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2274870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2275870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2276870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    status_t err = mOMX->getConfig(
2277870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2278870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2279870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = params.nRefreshPeriod;
2280870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2281870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2282870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2283870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Fallback to query through standard OMX index.
2284870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2285870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2286870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2287870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2288870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->getParameter(
2289870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, OMX_IndexParamVideoIntraRefresh, &refreshParams, sizeof(refreshParams));
2290870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK || refreshParams.nCirMBs == 0) {
2291870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2292870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2293870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2294870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2295870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Calculate period based on width and height
2296870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    uint32_t width, height;
2297870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_PARAM_PORTDEFINITIONTYPE def;
2298870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&def);
2299870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2300870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    def.nPortIndex = kPortIndexOutput;
2301870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->getParameter(
2302870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2303870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2304870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        *intraRefreshPeriod = 0;
2305870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2306870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2307870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    width = video_def->nFrameWidth;
2308870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    height = video_def->nFrameHeight;
2309870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Use H.264/AVC MacroBlock size 16x16
2310870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    *intraRefreshPeriod = divUp((divUp(width, 16u) * divUp(height, 16u)), refreshParams.nCirMBs);
2311870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2312870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2313870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2314870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2315870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuangstatus_t ACodec::setIntraRefreshPeriod(uint32_t intraRefreshPeriod, bool inConfigure) {
2316870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
2317870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&params);
2318870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nPortIndex = kPortIndexOutput;
2319870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    params.nRefreshPeriod = intraRefreshPeriod;
2320870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    status_t err = mOMX->setConfig(
2321870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            mNode, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh, &params, sizeof(params));
2322870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err == OK) {
2323870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return OK;
2324870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2325870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2326870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    // Only in configure state, a component could invoke setParameter.
2327870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (!inConfigure) {
2328870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return INVALID_OPERATION;
2329870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2330870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        ALOGI("[%s] try falling back to Cyclic", mComponentName.c_str());
2331870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2332870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2333870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    OMX_VIDEO_PARAM_INTRAREFRESHTYPE refreshParams;
2334870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    InitOMXParams(&refreshParams);
2335870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.nPortIndex = kPortIndexOutput;
2336870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    refreshParams.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic;
2337870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2338870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (intraRefreshPeriod == 0) {
2339870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // 0 means disable intra refresh.
2340870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = 0;
2341870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    } else {
2342870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Calculate macroblocks that need to be intra coded base on width and height
2343870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        uint32_t width, height;
2344870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_PARAM_PORTDEFINITIONTYPE def;
2345870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        InitOMXParams(&def);
2346870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2347870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        def.nPortIndex = kPortIndexOutput;
2348870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = mOMX->getParameter(
2349870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2350870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
2351870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            return err;
2352870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
2353870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        width = video_def->nFrameWidth;
2354870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        height = video_def->nFrameHeight;
2355870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        // Use H.264/AVC MacroBlock size 16x16
2356870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        refreshParams.nCirMBs = divUp((divUp(width, 16u) * divUp(height, 16u)), intraRefreshPeriod);
2357870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2358870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2359870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    err = mOMX->setParameter(mNode, OMX_IndexParamVideoIntraRefresh,
2360870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                             &refreshParams, sizeof(refreshParams));
2361870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (err != OK) {
2362870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        return err;
2363870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
2364870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2365870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    return OK;
2366870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang}
2367870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2400777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2401777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2402777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2403777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
24146e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24276e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
24286e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
24296e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)",
24306e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
24316e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eEncoding), format.eEncoding);
24326e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            return ERROR_UNSUPPORTED;
24336e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2441aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
24428045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
24432965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
24442965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2445ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2446ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2447ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2448ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2509aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2511b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2512b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2513b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2514b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2515b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2516b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2517b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2518b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2519b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2520b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2521b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2522b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2523b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2524b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2525b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2526b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2527b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2528b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2529b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2530b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2531b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2532b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2533b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2534b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2535b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2536b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2561ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2562ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2565ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25678045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
2568dabb051cf03b5ccc994c769a1cd23f9e6c378deeMarco Nelissen    InitOMXParams(&presentation);
25698045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
25708045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
25718045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
25728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
25738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
25748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
25752965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
25768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
25778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
25788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
25798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
25808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
25818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
25828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
25838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
25848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
25858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
258997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
259097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
259197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
259297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
259397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
259497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
259597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
259697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
259797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
259897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
259997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
260097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
260197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
260297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
260397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
260497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
260597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
260697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
260797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
260897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
260997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
261097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
261197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
261297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
261397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
261497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
261597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
261697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
261797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
261897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
261997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
262097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
262197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
262297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
262397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
262497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
262597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
26268a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
26278a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
26288a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
26298a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
26308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
26328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
26338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
26368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
26378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
26388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
26418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
26428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
26438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
26458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
26468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
26478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
26488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
26498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
26518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
26528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
26538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
26558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
26568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
26588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
26598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
26608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
26618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
26628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
26638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
26675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
26685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
26705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
26715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
26725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
26965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
26975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
26985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
26995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
27005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
27025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
27035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
27065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2710729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2711729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
27125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2713729de186450f78c099637e1fce743fe531862c52Andreas Huber
2714729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2715729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2716729de186450f78c099637e1fce743fe531862c52Andreas Huber
2717729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2718729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2719729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2720729de186450f78c099637e1fce743fe531862c52Andreas Huber
2721729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
27225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
27235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
27255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2726729de186450f78c099637e1fce743fe531862c52Andreas Huber
27275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
27285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2730729de186450f78c099637e1fce743fe531862c52Andreas Huber
27315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
27325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2735729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2736729de186450f78c099637e1fce743fe531862c52Andreas Huber
273717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2738777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2739777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2740777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2742729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
274317c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2744729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2745729de186450f78c099637e1fce743fe531862c52Andreas Huber
27462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
27472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
27482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
27502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
27512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
27522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
27532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
27552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
27562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
27572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
27582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
27592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
27602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
27612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
27622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
27632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
27642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
27652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
27662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
27672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
27682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
27692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
27702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
27712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
27722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
27732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2774729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2775729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2776729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2777729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2778729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2779729de186450f78c099637e1fce743fe531862c52Andreas Huber
2780729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2781729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2782729de186450f78c099637e1fce743fe531862c52Andreas Huber
2783729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2784729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2785729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2786729de186450f78c099637e1fce743fe531862c52Andreas Huber
2787729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2788729de186450f78c099637e1fce743fe531862c52Andreas Huber
2789729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2790729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2791729de186450f78c099637e1fce743fe531862c52Andreas Huber
2792729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2793729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2794729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2795729de186450f78c099637e1fce743fe531862c52Andreas Huber
2796729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2797729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2798729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2799729de186450f78c099637e1fce743fe531862c52Andreas Huber
2800729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2801729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2802729de186450f78c099637e1fce743fe531862c52Andreas Huber
2803729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2804729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2805729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2806729de186450f78c099637e1fce743fe531862c52Andreas Huber
2807729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2808729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2809729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2810729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2811729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2812729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2813729de186450f78c099637e1fce743fe531862c52Andreas Huber
2814c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2815c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2816729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2817729de186450f78c099637e1fce743fe531862c52Andreas Huber
2818729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2819729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2820729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2821729de186450f78c099637e1fce743fe531862c52Andreas Huber
28225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
282397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
28245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
28255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
28265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
28275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
28285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
28295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
28305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
28315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
28325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
28335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
28345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
28355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
28365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
28375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
28385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
28395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
28405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
28415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
28425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
28460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
28470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28546e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
2855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2864229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2865229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
28660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
28670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
28680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
28690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2870229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2871229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2872229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2873229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2874229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28996e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
29006e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking formats after %u: %s(%x)/%s(%x)",
29016e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
29026e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eCompressionFormat), format.eCompressionFormat,
29036e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    asString(format.eColorFormat), format.eColorFormat);
29046e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
29190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
29200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
29210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
29220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
29230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
29240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
29250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
29260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
29270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
29280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
29290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
29300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
29310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
29320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
29330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
29380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
29390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
29420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
29430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
29440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
29450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
29460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
29470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
29480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
29490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
29500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
29510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
29520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
29530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
29550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
29560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
29580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
29590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
29610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
29620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
29630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
29640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
29650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
29660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
29670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
29690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
29700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
29710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
29720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
29730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
29740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
29750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
29760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
29770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2984e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2985e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2986e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2987e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
29882472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2989e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2990e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2991e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
299294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
299394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2994a29c2b203d8bea8c21564765da5c9d7087448340Ronghua Wu    { MEDIA_MIMETYPE_VIDEO_DOLBY_VISION, OMX_VIDEO_CodingDolbyVision },
2995e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2996e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2999e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3000e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3001e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3002e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
3003e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
3004e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3008e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
3009e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3010e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
3011e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
3012e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3013e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
3014e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
3015e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
3016e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
3017e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
3018e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
3019e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
3020e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
3021e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
3022e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
3023e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3024e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
3025e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
3026e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
30308338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow,
3031b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool usingSwRenderer, sp<AMessage> &outputFormat) {
303289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
303389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
303489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
303589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
303689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
303789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
30385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
30395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
305389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
305489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
305589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
305689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
30570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
305889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
305989869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
306089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
30610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
306289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
306389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
30640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
306589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
307278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
307378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
307478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
307578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
307678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
307778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
307878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
307978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
308178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3094b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoDecoder(
3095b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            width, height, haveNativeWindow | usingSwRenderer, msg, outputFormat);
3096b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) { // support is optional
30978338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
30988338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3099b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3100b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3101b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3102b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::initDescribeColorAspectsIndex() {
3103b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = mOMX->getExtensionIndex(
3104b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mNode, "OMX.google.android.index.describeColorAspects", &mDescribeColorAspectsIndex);
3105b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err != OK) {
3106b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDescribeColorAspectsIndex = (OMX_INDEXTYPE)0;
3107b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3108b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3109b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
31108338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3111b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setCodecColorAspects(DescribeColorAspectsParams &params, bool verify) {
3112b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3113b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3114b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mOMX->setConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
3115b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3116b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3117b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3118b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3119b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3120b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3121b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3122b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3123b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3124b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (verify && err == OK) {
3125b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3126b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3127b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3128b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGW_IF(err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex,
3129b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "[%s] getting color aspects failed even though codec advertises support",
3130b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str());
31318338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    return err;
31328338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
31338338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3134b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoDecoder(
3135b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, bool usingNativeWindow,
3136b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
31378338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
31388338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3139b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
31408338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3141b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3142b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (usingNativeWindow) {
3143b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3144b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // The default aspects will be set back to the output format during the
3145b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // getFormat phase of configure(). Set non-Unspecified values back into the
3146b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // format, in case component does not support this enumeration.
3147b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, outputFormat);
31488338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
31498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3150b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
31518338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3152b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec
3153b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return setCodecColorAspects(params);
3154b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3155b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3156b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getCodecColorAspects(DescribeColorAspectsParams &params) {
3157b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = ERROR_UNSUPPORTED;
3158b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mDescribeColorAspectsIndex) {
3159b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mOMX->getConfig(mNode, mDescribeColorAspectsIndex, &params, sizeof(params));
31608338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3161b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) err=%d(%s)",
3162b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3163b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3164b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3165b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3166b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3167b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err, asString(err));
3168b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (params.bRequestingDataSpace) {
3169b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("for dataspace %#x", params.nDataSpace);
3170b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3171b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED && mDescribeColorAspectsIndex
3172b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            && !params.bRequestingDataSpace && !params.bDataSpaceChanged) {
3173b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW("[%s] getting color aspects failed even though codec advertises support",
3174b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3175b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3176b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3177b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
31788338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3179b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getInputColorAspectsForVideoEncoder(sp<AMessage> &format) {
3180b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3181b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3182b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3183b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = getCodecColorAspects(params);
3184b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3185b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // we only set encoder input aspects if codec supports them
3186b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setColorAspectsIntoFormat(params.sAspects, format, true /* force */);
31878338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3188b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3189b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3190b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3191b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getDataSpace(
3192b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        DescribeColorAspectsParams &params, android_dataspace *dataSpace /* nonnull */,
3193b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        bool tryCodec) {
3194b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3195b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (tryCodec) {
3196b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // request dataspace guidance from codec.
3197b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_TRUE;
3198b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = getCodecColorAspects(params);
3199b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        params.bRequestingDataSpace = OMX_FALSE;
3200b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK && params.nDataSpace != HAL_DATASPACE_UNKNOWN) {
3201b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace = (android_dataspace)params.nDataSpace;
3202b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3203b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else if (err == ERROR_UNSUPPORTED) {
3204b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // ignore not-implemented error for dataspace requests
3205b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = OK;
3206b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
32078338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3208b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3209b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // this returns legacy versions if available
3210b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = getDataSpaceForColorAspects(params.sAspects, true /* mayexpand */);
3211b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("[%s] using color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
3212b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "and dataspace %#x",
3213b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mComponentName.c_str(),
3214b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mRange, asString(params.sAspects.mRange),
3215b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mPrimaries, asString(params.sAspects.mPrimaries),
3216b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mMatrixCoeffs, asString(params.sAspects.mMatrixCoeffs),
3217b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params.sAspects.mTransfer, asString(params.sAspects.mTransfer),
3218b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            *dataSpace);
3219b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3220b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3221b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3222b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3223b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::getColorAspectsAndDataSpaceForVideoDecoder(
3224b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, int32_t height, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat,
3225b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace) {
3226b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3227b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3228b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexOutput;
3229b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3230b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and get resulting format
3231b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3232b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3233b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
32348338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3235b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = setCodecColorAspects(params, true /* readBack */);
32368338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3237b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // we always set specified aspects for decoders
3238b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(params.sAspects, outputFormat);
3239b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3240b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (dataSpace != NULL) {
3241b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t res = getDataSpace(params, dataSpace, err == OK /* tryCodec */);
3242b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err == OK) {
3243b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            err = res;
3244b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
32458338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
32468338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3247b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
32488338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar}
32498338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3250b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// initial video encoder setup for bytebuffer mode
3251b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setColorAspectsForVideoEncoder(
3252b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
3253b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // copy config to output format as this is not exposed via getFormat
3254b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    copyColorConfig(configFormat, outputFormat);
3255b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3256b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    DescribeColorAspectsParams params;
3257b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    InitOMXParams(&params);
3258b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
3259b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(configFormat, params.sAspects);
3260b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3261b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    (void)initDescribeColorAspectsIndex();
3262b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3263b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t usingRecorder;
3264b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (configFormat->findInt32("android._using-recorder", &usingRecorder) && usingRecorder) {
3265b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace dataSpace = HAL_DATASPACE_BT709;
3266b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t width, height;
3267b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (configFormat->findInt32("width", &width)
3268b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && configFormat->findInt32("height", &height)) {
3269b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setDefaultCodecColorAspectsIfNeeded(params.sAspects, width, height);
3270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            status_t err = getDataSpace(
3271b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    params, &dataSpace, mDescribeColorAspectsIndex /* tryCodec */);
3272b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            if (err != OK) {
3273b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                return err;
3274b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            }
3275b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            setColorAspectsIntoFormat(params.sAspects, outputFormat);
3276b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3277b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        inputFormat->setInt32("android._dataspace", (int32_t)dataSpace);
32788338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
32798338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3280b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow change of the platform aspects
3281b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = params.sAspects;
3282b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; --triesLeft >= 0; ) {
3283b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3284b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK
3285b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(
3286b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        params.sAspects, origAspects, true /* usePlatformAspects */)) {
3287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
3288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
3291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
3292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return OK;
3293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
3294b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar// subsequent initial video encoder setup for surface mode
3296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarstatus_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
3297b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        android_dataspace *dataSpace /* nonnull */) {
32988338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    DescribeColorAspectsParams params;
32998338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    InitOMXParams(&params);
3300b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    params.nPortIndex = kPortIndexInput;
33018338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    ColorAspects &aspects = params.sAspects;
33028338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3303b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // reset default format and store resulting format into both input and output formats
3304b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    getColorAspectsFromFormat(mConfigFormat, aspects);
3305b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t width, height;
3306b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mInputFormat->findInt32("width", &width) && mInputFormat->findInt32("height", &height)) {
3307b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        setDefaultCodecColorAspectsIfNeeded(aspects, width, height);
33088338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3309b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mInputFormat);
3310b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    setColorAspectsIntoFormat(aspects, mOutputFormat);
33118338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3312b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // communicate color aspects to codec, but do not allow any change
3313b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ColorAspects origAspects = aspects;
3314b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err = OK;
3315b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    for (int triesLeft = 2; mDescribeColorAspectsIndex && --triesLeft >= 0; ) {
3316b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = setCodecColorAspects(params, true /* readBack */);
3317b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK || !ColorUtils::checkIfAspectsChangedAndUnspecifyThem(aspects, origAspects)) {
3318b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            break;
3319b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
3320b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(triesLeft == 0, "[%s] Codec repeatedly changed requested ColorAspects.",
3321b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mComponentName.c_str());
33228338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
33238338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3324b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    *dataSpace = HAL_DATASPACE_BT709;
3325b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    aspects = origAspects; // restore desired color aspects
3326b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t res = getDataSpace(
3327b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            params, dataSpace, err == OK && mDescribeColorAspectsIndex /* tryCodec */);
3328b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3329b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = res;
33308338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3331b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setInt32("android._dataspace", (int32_t)*dataSpace);
3332b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mInputFormat->setBuffer(
3333b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            "android._color-aspects", ABuffer::CreateAsCopy(&aspects, sizeof(aspects)));
3334b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3335b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // update input format with codec supported color aspects (basically set unsupported
3336b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects to Unspecified)
3337b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
3338b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        (void)getInputColorAspectsForVideoEncoder(mInputFormat);
33398338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
3340b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3341b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGV("set default color aspects, updated input format to %s, output format to %s",
3342b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mInputFormat->debugString(4).c_str(), mOutputFormat->debugString(4).c_str());
3343b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
3344b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    return err;
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33478338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnarstatus_t ACodec::setupVideoEncoder(
3348b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        const char *mime, const sp<AMessage> &msg,
3349b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        sp<AMessage> &outputFormat, sp<AMessage> &inputFormat) {
33505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
33515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
33525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
33535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
33565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
33575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
33595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
33605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
33635778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
33645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
33665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
33695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
33715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
33725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
33745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
33765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
33785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
33795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
33825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
33855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
33865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
33875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
33885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
33895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
33925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
33935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
33955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
34005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
34035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
34045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
34095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
34115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
34125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
34135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
34145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
34155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
34165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
34172c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
34185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
34215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
3422a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
3423a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
3424a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
3425a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
3426a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
34275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
34295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
34305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
34395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
34485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
34495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
34525778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
34535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
34585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
34605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
34615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
34675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
34685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
34695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
34705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
34715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
34725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
34745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
34755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
34785778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
34795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3483870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
3484870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (msg->findInt32("intra-refresh-period", &intraRefreshPeriod)
3485870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod >= 0) {
3486870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        err = setIntraRefreshPeriod((uint32_t)intraRefreshPeriod, true);
3487870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
3488870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
3489870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
3490870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
3491870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
3492870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
3493870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
34945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
34955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
34965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
34975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
34985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
35005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
35015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
35055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3507c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3508c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3509c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3510c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
351189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
351289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
351389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
351489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
351589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
35165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
35175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35208338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // Set up color aspects on input, but propagate them to the output format, as they will
35218338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    // not be read back from encoder.
3522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    err = setColorAspectsForVideoEncoder(msg, outputFormat, inputFormat);
3523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == ERROR_UNSUPPORTED) {
35248338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        ALOGI("[%s] cannot encode color aspects. Ignoring.", mComponentName.c_str());
35258338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar        err = OK;
35268338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar    }
35278338519ba2d8d731072c4edf7b9953787ce834cfLajos Molnar
3528d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3529d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3530d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
35360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
35370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
35380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
35390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
35400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
35410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
35420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
35430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
35440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
35450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
35460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
35470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
35480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
35490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
35500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
35510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
35520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
35530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
35540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
35550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
35560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
35570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
35580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
35590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
35600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
35610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
35620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
35630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
35640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
35650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
35660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
35670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
35680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
35690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
35700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
35710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
35725778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
35735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
35765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
35795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
35805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
358296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
358396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
358496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
358596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
358696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
358796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
358896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
358996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
359096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
35945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
359896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
359996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
36005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
36025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
36045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
36055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
36105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
36115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
36285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
36295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
36405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
36415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
36425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
36435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
36445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
36475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
36495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
36575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
366396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
36705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36725778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
36735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
36745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
36755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
36765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
36775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
367996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
368096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
37095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
37295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
37335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
37345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
373996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
37405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
37435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3748a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3749a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3750a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3751a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3752a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3753a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3754a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3755a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3756a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3757a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3758a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3759a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3760a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3761a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3762a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3763a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3764a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3765a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3766a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3767a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3768a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3769a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3770a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3771a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3772a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3773a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3774a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3775a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3776a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3777a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3778a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3779a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3780a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3781a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3782a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3783a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3784a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3785a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3786a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3787a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3788a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3789a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3790a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3791a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3792a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3793a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3794a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3795a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3796a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3797a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3798a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3799a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
38005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
380796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
380896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
38105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
38115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
38125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
38135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
38165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
38190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
38200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
38210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
38220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
38230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
38240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
38250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
38260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
38270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
38280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
38295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
38305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
38345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
38385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
38415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
38425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
38445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
38455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
38465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
38475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
38485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
38515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
38535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
38635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
38645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
38655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
38665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
38675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
38715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
38745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
38755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
38765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
38775207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang    } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
38785207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang            h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
38795207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nSliceHeaderSpacing = 0;
38805207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bUseHadamard = OMX_TRUE;
38815207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nRefFrames = 2;
38825207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nBFrames = 1;
38835207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
38845207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nAllowedPictureTypes =
38855207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang            OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
38865207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nRefIdx10ActiveMinus1 = 0;
38875207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nRefIdx11ActiveMinus1 = 0;
38885207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bEntropyCodingCABAC = OMX_TRUE;
38895207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bWeightedPPrediction = OMX_TRUE;
38905207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bconstIpred = OMX_TRUE;
38915207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bDirect8x8Inference = OMX_TRUE;
38925207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.bDirectSpatialTemporal = OMX_TRUE;
38935207ffe7a35148a1e4ea188cf2224fb230a92a0eHangyu Kuang        h264type.nCabacInitIdc = 1;
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
38975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
38985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
39015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
39025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
39035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
39075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
39095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
39105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
39125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
39135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
39145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
391596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
39165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3918c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3919c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3920c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3921c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3922c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3923c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3924c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3925c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3926c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3927c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3928c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3929c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3930c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3931c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3932c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3933c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3934c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3935c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3936c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3937c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3938c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3939c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3940c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3941c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3942c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3943c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3944c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3945c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3946c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3947c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3948c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3949c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3950c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3951c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3952c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3953c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3954c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3955c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3956c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3957c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3958c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3959c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3960c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3961c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
39629aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    // TODO: finer control?
39639aa87d4ef502c9700a31fe46dc6e1d6f99cf4e5eWonsik Kim    hevcType.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
3964c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3965c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3966c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3967c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3968c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3969c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3970c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3971c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3972c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3973c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
397489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
397589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
39764154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
39774154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
39784154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
39794154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
39804154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
39814154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
39824154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
39834154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
39844154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
39854154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
39864154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
398789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
398889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
398989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
39904154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
399189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
399289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
399389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
39944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
39954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
39964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
39974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
39984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
39994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
40014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
40024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
40034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
40044154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
40054154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
40064154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
40074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
40084154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
40094154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
40104154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
40114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
40124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
40134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
40144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
40154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
40164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
40184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
40194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
40204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
40214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
40224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
40234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
40244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
40254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
40264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
40274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
40284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
40294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
40314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
40324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
40334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
40344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
40354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
40364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
40374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
40394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
40404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
40414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
40434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
40444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
40454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
40464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
40474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
40484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
40494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
40504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
405189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
405289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
405389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
40545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
40555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
40565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
40575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
40585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
40595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
40616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        params.nProfileIndex = index;
40625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
40635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
40645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
40655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
40665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
40675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
40695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
40705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
40735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
40745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
40765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
40775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
40786e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
40796e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        if (index == kMaxIndicesToCheck) {
40806e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            ALOGW("[%s] stopping checking profiles after %u: %x/%x",
40816e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    mComponentName.c_str(), index,
40826e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                    params.eProfile, params.eLevel);
40836e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        }
40845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
40856e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar    return ERROR_UNSUPPORTED;
40865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
408896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
408996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
40905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
40915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
40925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
40935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
40955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
40965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
40975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
40995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
41005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
410296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
41035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
41045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
41065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
41075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
41085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
41115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
41125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
41135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
41145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
41165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
41175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
41185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
41205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
41215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
41225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
41245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
41255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
41265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
41275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
41285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
41305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
41315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
41325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
41335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
413678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
413778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4146777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4147777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4148777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4158777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
4159777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
4160777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
4161777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
416978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
417078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
417178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
4182a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4185a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4189d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
4190d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
4191d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4192d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4193d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
4194d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4195d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4196d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
4197d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
4198d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
4199d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4200d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
4201d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
4202d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
42037e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
42047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
42057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
42077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
42087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
42107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
42117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
42127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
42137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
42157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
42167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
42177e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
42187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
42197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
42207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
42217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4222e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
42237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
4224c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
4225054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
4226054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
4227c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
42287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
42297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
42307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4238609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
426703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
426873dd808754c641fe798273d356ee38368715fa7bLajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormat2Params &params) {
426973dd808754c641fe798273d356ee38368715fa7bLajos Molnar    MediaImage2 &image = params.sMediaImage;
427003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
427103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
427273dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mType = MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
427303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
427403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
427503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
427603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
427703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
427803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
427903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
428003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
428103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
428203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
42835a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
42842ad160ba086f0504cf56dcc24619a0cee2546a23Dan Stoza        fmt != (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YV12) {
428503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
4286229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
428703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
428803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4289b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
4290b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
4291b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
4292b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
4293b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
4294b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
4295b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
429634e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // we need stride and slice-height to be non-zero and sensible. These values were chosen to
429734e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // prevent integer overflows further down the line, and do not indicate support for
429834e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    // 32kx32k video.
429934e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen    if (params.nStride == 0 || params.nSliceHeight == 0
430034e63e9ffe6496d9180c825dc119c1fd1020ef8bMarco Nelissen            || params.nStride > 32768 || params.nSliceHeight > 32768) {
4301b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
4302b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
4303b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
4304b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
4305b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
430603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
430773dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mType = MediaImage2::MEDIA_IMAGE_TYPE_YUV;
430803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
430903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
431073dd808754c641fe798273d356ee38368715fa7bLajos Molnar    image.mBitDepthAllocated = 8;
431103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
431203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
431303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
431403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
431503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
431603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
43175a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
43185a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
43195a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
43205a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
43215a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
43225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
43235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
43245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
43255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
43265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
43275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
43285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
43295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
43305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
43315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
43325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
43335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
43345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
43355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
43365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
43375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
43385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
43395a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
43405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
43415a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
434203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
434303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
434403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
434503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
434603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
434703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
434803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
434903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
435003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
435103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
435203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
435303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
435403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
435503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
435603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
435703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
435803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
435903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
436003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
436103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
436203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
436303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
436403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
436503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
436603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
436703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
436803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
436903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
437003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
437103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
437203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
437303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
437403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
437503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
437603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
4377229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
4378229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
4379229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4380229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
4381229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
4382229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
438373dd808754c641fe798273d356ee38368715fa7bLajos Molnar        DescribeColorFormat2Params &describeParams)
4384229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
4385229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
4386229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
4387229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
438873dd808754c641fe798273d356ee38368715fa7bLajos Molnar            &describeColorFormatIndex) == OK) {
438973dd808754c641fe798273d356ee38368715fa7bLajos Molnar        DescribeColorFormatParams describeParamsV1(describeParams);
439073dd808754c641fe798273d356ee38368715fa7bLajos Molnar        if (omx->getParameter(
439173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                node, describeColorFormatIndex,
439273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                &describeParamsV1, sizeof(describeParamsV1)) == OK) {
439373dd808754c641fe798273d356ee38368715fa7bLajos Molnar            describeParams.initFromV1(describeParamsV1);
439473dd808754c641fe798273d356ee38368715fa7bLajos Molnar            return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
439573dd808754c641fe798273d356ee38368715fa7bLajos Molnar        }
439673dd808754c641fe798273d356ee38368715fa7bLajos Molnar    } else if (omx->getExtensionIndex(
439773dd808754c641fe798273d356ee38368715fa7bLajos Molnar            node, "OMX.google.android.index.describeColorFormat2", &describeColorFormatIndex) == OK
439873dd808754c641fe798273d356ee38368715fa7bLajos Molnar               && omx->getParameter(
439973dd808754c641fe798273d356ee38368715fa7bLajos Molnar            node, describeColorFormatIndex, &describeParams, sizeof(describeParams)) == OK) {
440073dd808754c641fe798273d356ee38368715fa7bLajos Molnar        return describeParams.sMediaImage.mType != MediaImage2::MEDIA_IMAGE_TYPE_UNKNOWN;
440173dd808754c641fe798273d356ee38368715fa7bLajos Molnar    }
440273dd808754c641fe798273d356ee38368715fa7bLajos Molnar
440373dd808754c641fe798273d356ee38368715fa7bLajos Molnar    return describeDefaultColorFormat(describeParams);
4404229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
4405229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4406229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
4407229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
4408229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
44090d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
441073dd808754c641fe798273d356ee38368715fa7bLajos Molnar    DescribeColorFormat2Params describeParams;
4411229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
4412229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
4413229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
4414229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
4415229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
4416229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
4417229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
44180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
4419229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4420229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
4421229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4422229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
4423229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
4424229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
4425229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
442673dd808754c641fe798273d356ee38368715fa7bLajos Molnar    const MediaImage2 &img = describeParams.sMediaImage;
442773dd808754c641fe798273d356ee38368715fa7bLajos Molnar    if (img.mType == MediaImage2::MEDIA_IMAGE_TYPE_YUV) {
442873dd808754c641fe798273d356ee38368715fa7bLajos Molnar        if (img.mNumPlanes != 3
442973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                || img.mPlane[img.Y].mHorizSubsampling != 1
443073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                || img.mPlane[img.Y].mVertSubsampling != 1) {
4431229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
4432229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
4433229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
4434229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
4435229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
4436229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
4437229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
4438229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
4439229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
4440229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
4441229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
4442229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
4443229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
4444229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
4445229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
4446229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
444703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
444803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4449e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
4450777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
445131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
445231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
4453e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
445431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4455777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
4456777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
4457777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
4458777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
445931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4460777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
4461777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
4462777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
4463777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
446431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
446531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
446631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
446731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
446831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
4469e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
4470e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
4471e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4472e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
4473e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
4474e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4475e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
4476e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
4477e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
4478e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
44790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
448073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                        DescribeColorFormat2Params describeParams;
44810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
44820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
44830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
44840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
44850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
44860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
44870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
44880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
44890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
44900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
44910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
44920d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
44930d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
44940d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
44955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
449673dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2 &img = describeParams.sMediaImage;
449773dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            MediaImage2::PlaneInfo *plane = img.mPlane;
449873dd808754c641fe798273d356ee38368715fa7bLajos Molnar                            ALOGV("[%s] MediaImage { F(%ux%u) @%u+%d+%d @%u+%d+%d @%u+%d+%d }",
449973dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    mComponentName.c_str(), img.mWidth, img.mHeight,
450073dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[0].mOffset, plane[0].mColInc, plane[0].mRowInc,
450173dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[1].mOffset, plane[1].mColInc, plane[1].mRowInc,
450273dd808754c641fe798273d356ee38368715fa7bLajos Molnar                                    plane[2].mOffset, plane[2].mColInc, plane[2].mRowInc);
45030d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
450403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
450503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
4506b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t width = (int32_t)videoDef->nFrameWidth;
4507b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    int32_t height = (int32_t)videoDef->nFrameHeight;
4508b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4509b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    if (portIndex == kPortIndexOutput) {
4510b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        OMX_CONFIG_RECTTYPE rect;
4511b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        InitOMXParams(&rect);
4512b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        rect.nPortIndex = portIndex;
4513b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4514b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mOMX->getConfig(
4515b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    mNode,
4516b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    (portIndex == kPortIndexOutput ?
4517b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonOutputCrop :
4518b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                            OMX_IndexConfigCommonInputCrop),
4519b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    &rect, sizeof(rect)) != OK) {
4520b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft = 0;
4521b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop = 0;
4522b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nWidth = videoDef->nFrameWidth;
4523b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nHeight = videoDef->nFrameHeight;
4524b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
452591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (rect.nLeft < 0 ||
4527b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop < 0 ||
4528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft, rect.nTop,
4532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    videoDef->nFrameWidth, videoDef->nFrameHeight);
4534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            return BAD_VALUE;
4535b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
453631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        notify->setRect(
4538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                "crop",
4539b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft,
4540b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop,
4541b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nLeft + rect.nWidth - 1,
4542b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                rect.nTop + rect.nHeight - 1);
4543b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4544b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        width = rect.nWidth;
4545b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        height = rect.nHeight;
4546b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4547b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
4548b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getColorAspectsAndDataSpaceForVideoDecoder(
4549b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                width, height, mConfigFormat, notify,
4550b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mUsingNativeWindow ? &dataSpace : NULL);
4551b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mUsingNativeWindow) {
4552b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            notify->setInt32("android._dataspace", dataSpace);
4553b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
4554b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    } else {
4555b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        (void)getInputColorAspectsForVideoEncoder(notify);
4556777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4558e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4559e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
45604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
45614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
45624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
45634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
45644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
45654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
45664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
45674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
45684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
45694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
45704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
45714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
45724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
45734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
45744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
45754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
45764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
45774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
45784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
45794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
45804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
45814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
45824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
45834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
45844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
45854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
45864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
45874730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
45884730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
45894730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
45904730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
45914730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
45924730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
45934730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
45944730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
45954730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
45964730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
45974730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
45984730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
45994730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
46004730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
46014730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
46024730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
46034730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4604e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4605e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4606777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4607777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4608777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4609777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4610777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4611777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4612777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4613e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4614e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4615e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4616e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4617e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4618e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4619e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4620870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    uint32_t intraRefreshPeriod = 0;
4621870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    if (mIsEncoder && getIntraRefreshPeriod(&intraRefreshPeriod) == OK
4622870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                            && intraRefreshPeriod > 0) {
4623870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                        notify->setInt32("intra-refresh-period", intraRefreshPeriod);
4624870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    }
4625e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
462731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4628e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4629e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
46305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
46315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
46325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
46335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
463431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
463531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
463631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
463731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
463831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
463931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
464031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
464197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4646e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4648777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4649777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4650777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4651777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4652777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
465314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4654777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4655777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4656777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.nBitPerSample != 16u
4657777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.eNumData != OMX_NumericalDataSigned
4658777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
4659777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
4660777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4661777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
4662777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nBitPerSample,
4663777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.eNumData), params.eNumData,
4664777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.ePCMMode), params.ePCMMode);
4665777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4666777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
467178bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
4672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
46758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
46778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
46789806555d3930be43e11106281dee354820ac1c88Andreas Huber
4679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4683e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4685777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4686777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4687777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4688777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4689777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
47029806555d3930be43e11106281dee354820ac1c88Andreas Huber
4703777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4704777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4705777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4706777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
47110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
47140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4726777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4727777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4728777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4729777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4730777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4738e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4739e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4740e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4741e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4743e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4744777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4745777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4746777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4747777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4748777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4749e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4750e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4751e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4752e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4753e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4754e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4755e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4756e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4757e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4758e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4759e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4760e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4761e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4762777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4763777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4764777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4765777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4766777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4767e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4768e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4769e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4770e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4771e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4772e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
477497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
477597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
477697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
477797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4778e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
477997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4780777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4781777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4782777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4783777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4784777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4785777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
478697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
478797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
478897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
478997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
479097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
479197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
47938a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
47948a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
47958a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
47968a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
47978a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
47988a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4799777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4800777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4801777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4802777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4803777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4804777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
48058a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
48068a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
48078a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
48088a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
48098a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
48108a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
48118a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
48128c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
48138c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
48148c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
48158c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
48168c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
48178c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4818777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4819777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4820777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4821777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4822777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4823777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
48248c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
48258c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
48268c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
48278c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
48288c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
48298c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
48308c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
483110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
483210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
483310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
483410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
483510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
483610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4837777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4838777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4839777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4840777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4841777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
484210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
484310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
484410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
484510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
484610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
484710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
484810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
484910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
485010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
485110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
485210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
485310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
485478bd91b15ee8ea5aa2ab5a8cad7e892cb2d01c1bLajos Molnar                    notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
485510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
485610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
485741d3f579d2c166984958263533284209b90c87d5Marco Nelissen
485841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
485941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
48600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
486141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
486241d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
486341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4864777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4865777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4866777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4867777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4868777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
486941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
487041d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
487141d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
48720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
487341d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
487410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
487510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4877777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4878777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4879777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
488131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
488231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
488331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
488431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4885777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4886777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
488731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
488831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4889e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4890e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4891e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4892b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
4893b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // aspects are normally communicated in ColorAspects
4894b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t range, standard, transfer;
4895b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer);
4896b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4897b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // if some aspects are unspecified, use dataspace fields
4898b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
4899b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        range = (dataSpace & HAL_DATASPACE_RANGE_MASK) >> HAL_DATASPACE_RANGE_SHIFT;
4900b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4901b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
4902b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK) >> HAL_DATASPACE_STANDARD_SHIFT;
4903b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4904b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
4905b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK) >> HAL_DATASPACE_TRANSFER_SHIFT;
4906b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4907b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4908b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
4909b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (range != 0) {
4910b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-range", range);
4911b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4912b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (standard != 0) {
4913b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-standard", standard);
4914b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4915b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (transfer != 0) {
4916b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mOutputFormat->setInt32("color-transfer", transfer);
4917b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
4918b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4919b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    ALOGD("dataspace changed to %#x (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) "
4920b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar          "(R:%d(%s), S:%d(%s), T:%d(%s))",
4921b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            dataSpace,
4922b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mRange, asString(aspects.mRange),
4923b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mPrimaries, asString(aspects.mPrimaries),
4924b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs),
4925b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            aspects.mTransfer, asString(aspects.mTransfer),
4926b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            range, asString((ColorRange)range),
4927b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            standard, asString((ColorStandard)standard),
4928b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            transfer, asString((ColorTransfer)transfer));
4929b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar}
4930b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4931b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::onOutputFormatChanged() {
4932b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // store new output format
4933b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mOutputFormat = mBaseOutputFormat->dup();
4934e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4935b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
4936777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4937777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
4938777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4939e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4940b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mTunneled) {
4941b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        sendFormatChange();
4942b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
4943b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
4944b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
4945b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarvoid ACodec::addKeyFormatChangesToRenderBufferNotification(sp<AMessage> &notify) {
4946e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4947b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
4948e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4949b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW && mNativeWindow != NULL) {
4950b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        // notify renderer of the crop change and dataspace change
4951e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4952b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t left, top, right, bottom;
4953b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
4954b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setRect("crop", left, top, right + 1, bottom + 1);
4955b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
4956b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
4957b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        int32_t dataSpace;
4958b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
4959b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            notify->setInt32("dataspace", dataSpace);
4960b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
4961b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    }
4962b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar}
4963b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
4964b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnarvoid ACodec::sendFormatChange() {
4965b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    AString mime;
4966b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    CHECK(mOutputFormat->findString("mime", &mime));
4967b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
4968b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    if (mime == MEDIA_MIMETYPE_AUDIO_RAW && (mEncoderDelay || mEncoderPadding)) {
4969e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4970b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar        CHECK(mOutputFormat->findInt32("channel-count", &channelCount));
4971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4974ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4976e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4977b1cf03160fa7e7bc6e5cf138db07a7e1ab2ecb26Marco Nelissen        mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
4978e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4979e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4980b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    sp<AMessage> notify = mNotify->dup();
4981b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4982b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    notify->setMessage("format", mOutputFormat);
498331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
498431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4985b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    // mLastOutputFormat is not used when tunneled; doing this just to stay consistent
4986b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mLastOutputFormat = mOutputFormat;
498731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
498831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
49895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4990cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4991d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4992251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4993251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4994251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4995251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4996251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4997251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4998251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4999251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
5000251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
5001251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5002346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
5003346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang    mFatalError = true;
5004346de3c26a8fbd0fa0c8102f4a21ea4dcee4432aChong Zhang
50055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
5006251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
5007cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
5008cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
5009cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
5010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5012eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
5013eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5014eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5015496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
5016496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
5017496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
5018496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
5019496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5020496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
5021496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
5022496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5023496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
5024496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
5025496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5026496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
5027496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
5028496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
5029496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
5030496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
5031496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
5032496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
5033eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
5034a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        IOMX::buffer_id id, const sp<ABuffer> &buffer,
5035a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
5036eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
5037eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
5038a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    mHandles.push_back(handle);
503986b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    mMemRefs.push_back(memRef);
5040eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5041eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5042eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
5043eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
5044eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5045eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5046eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
5047eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
5048eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5049eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5050eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
5051eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
5052eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
5053eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5054a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnarsp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
5055a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar    return mHandles.itemAt(index);
5056a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar}
5057a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar
505886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wusp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
505986b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    return mMemRefs.itemAt(index);
506086b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu}
506186b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu
5062eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
5063eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5064f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
5065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
5066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
5067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5069ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
5070ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
5072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5074f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
5075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
5077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
5079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
5083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
5085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
508926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
509026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
509126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
509226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
5093e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        case ACodec::kWhatOMXMessageItem:
5094e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        {
5095e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            // no need to check as we already did it for kWhatOMXMessageList
5096e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar            return onOMXMessage(msg);
5097e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        }
5098e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar
5099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
5100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
510126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
5102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
51051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
51061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
51071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
51081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
51091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
51101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
51111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
51122235b4efd3b8149e09c666e2235530f3e6ed9c9aLajos Molnar            status_t err = mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
51131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
51141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
51151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
51161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
51171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
51181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
51191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
51207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
51218f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
51227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
51237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
5124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
51257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
51267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
51277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
51287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
51297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5130ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
5131ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
5132251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
5133ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
5134ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
5135ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
5136ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
5137ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
513830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
513930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
514030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
514130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
514230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
514330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
514430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
514530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
514630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
514730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
514830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
514930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
515030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
5153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
515826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
51595e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
51605e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
5161ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
51625e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
51635e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
516426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
51655e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
51665e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
5167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
5168609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
5169777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
5170777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
5171777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
5172777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
517326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
517426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
517526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
517626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
517726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
517826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
517926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
518026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
518190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
518226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
518326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
5184e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        (*it)->setWhat(ACodec::kWhatOMXMessageItem);
5185e421a32aa696cd8abbf8fdc97cc8f37dbf372cacLajos Molnar        mCodec->handleMessage(*it);
518690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
518790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
518890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
518990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
519090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
519190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
519290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
519390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
519490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
519590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
519626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
519726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
519826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
519926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
520026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
520126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
520226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
5203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
5205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
5206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
5208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
5209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
5210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
5211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
52130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
52140af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
52150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
52160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
52170af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
52180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
52190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
52200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
52210af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
52220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
5223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
5225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
5226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
5227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
5230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
523215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
523315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5234609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
523515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
523715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
5243609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
524515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
525215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
5256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
525815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
525915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
5260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
526290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
526390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
526490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
526590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
526690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
526790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
526890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
526990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
527090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
527190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
527290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5274777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
5275777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
527990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
528090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
528190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
528290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
528390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
528490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5285f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
5286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5287b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (event == OMX_EventDataSpaceChanged) {
5288b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ColorAspects aspects;
5289b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mRange = (ColorAspects::Range)((data2 >> 24) & 0xFF);
5290b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mPrimaries = (ColorAspects::Primaries)((data2 >> 16) & 0xFF);
5291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)((data2 >> 8) & 0xFF);
5292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        aspects.mTransfer = (ColorAspects::Transfer)(data2 & 0xFF);
5293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5294b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->onDataSpaceChanged((android_dataspace)data1, aspects);
5295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        return true;
5296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5297b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
5299ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
5300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
5301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
5303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
5306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5307251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
5308251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
5309251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
5310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
5311251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
5312251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
5313251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
5314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
531815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
5319ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
5320349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
5321349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
53220806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
53230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
53240806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
53250806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
53260806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
532715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
532815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
532915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
53300806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
53310806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
533415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
533515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
533615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
533715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
533815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
533915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
534015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
534196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
534296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
534396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
534496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
534596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
534696e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
5347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5358777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5360777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
5361777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5367f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
5375d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
5376609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
5377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
53792d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
5380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53811d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
5382609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
5383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
5385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
5387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
5389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5391f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
5392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5393609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
53942d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
53965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
5397a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
53985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
53992d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
5400a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
5401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
5402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54037fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
54047fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
54057fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
54067fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
54077fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
54087fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
54097fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
54107fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
54113831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
54122d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
5413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
54165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
54175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
54185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
54195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
54205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
54220806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
54230806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
54240806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
54250806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
54260806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
54270806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
54280806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
54355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
5436dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
5437dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
5438dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
5439dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
54465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
5447fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                // Do not send empty input buffer w/o EOS to the component.
5448fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                if (buffer->size() == 0 && !eos) {
5449fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    postFillThisBuffer(info);
5450fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                    break;
5451fd866b3aa0d97375de08f8888b95669026c83361Wei Jia                }
5452fd866b3aa0d97375de08f8888b95669026c83361Wei Jia
5453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
5454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
5457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
5459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
5460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
5461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
54645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
54655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
54665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
5468ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
5469d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
5470d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
5471d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
5472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (buffer->size() > info->mData->capacity()) {
54740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
54750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                buffer->size(),           // this is the data received
54760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                info->mData->capacity()); // this is out buffer size
54770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
54780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
54790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
5481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5483078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
5484ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
5485078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
54865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
5487ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
54885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
5489078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
5490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5491ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
5492ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
5494ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
5495ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
5496d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5497078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
5498349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5499d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
5501d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
5502d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
5503d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
5504d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5505d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5506054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
5507054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
5508054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
5509054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5510054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
5511054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
5512054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
5513054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
5514054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
5515054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
5516054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
5517054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
551815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
55190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
55200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode,
55210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    bufferID,
55220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    0,
55230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    buffer->size(),
55240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    flags,
552515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
552615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd);
552715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
55280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
55290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
55300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
55310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55340806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
55355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
55365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
55370806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
55380806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
55395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
55405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
55415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
55425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
55440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
55450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
5546dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
5547dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
55483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
5549dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
5550dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
5551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5552ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
5553349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
5554349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
555515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
55560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
55570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
55580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
55590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
55600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
55610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
556215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
556315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
556415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
55650806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
55660806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
55670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
55680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
5570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
5572dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
5573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5576625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
5577777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5578777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
5579777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5580625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
5581777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
5582625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
5583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5586f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
5587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
5588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
5592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
5597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
5598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
5599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
5600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
5602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
5604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
5605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
5609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
5610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
5613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5615f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
5616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
561915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
562015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5621609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
56225778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5623349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
56250806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5626d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5628d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5629d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5630d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5631d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5632d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5633d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5634d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5635d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5636d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5637d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5638d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5639d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5641d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
56440806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
56450806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
56460806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
56470806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
56480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
564915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
565015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
565115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
56520806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
56530806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
565890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
565990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
566090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
566190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
566290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
566390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
566490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
566590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
566690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
566715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
566815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
566915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
567015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
567115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
567215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
567315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5682a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5683a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5684609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
56855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5686349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
568715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
568815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
56890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
56900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
56910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
56920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
56955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
56965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
569731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5698577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
56991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
5700577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5701b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
5702b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
5703b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                mCodec->sendFormatChange();
57045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5705b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
5706054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
5707054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
5708054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
5709054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
5710054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (info->mData->size() >= sizeof(grallocMeta)
5711054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
57127c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
5713054219874873b41f1c815552987c10465c34ba2bLajos Molnar                } else if (info->mData->size() >= sizeof(nativeMeta)
5714054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
57157c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
57167c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
57177c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar                    handle = NULL;
57187c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#else
5719054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
57207c77f9ca649f321374118937bcdaca14a7e5684bLajos Molnar#endif
5721054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
5722308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
5723308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5724308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
5725308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
5726308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
5727308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
5728496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
572921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
5730496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
5731496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
5732496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
57335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
573421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
5735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57368b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
57378b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
57388b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
57395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
5740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5742d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5743609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
57442d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
57455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
5746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5747609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
5748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
5750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
57515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
57525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
57565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
57575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
5759d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
5760dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
5761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
5762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
5764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5768777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
57690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
57700806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
57710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
57720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
57730806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5775777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5776777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5777777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5778777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5784f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5786609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
57880806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
57890806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
57900806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
57910806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
57920806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
57930806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
57940806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
57950806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5797577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
5798777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5799777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5800777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5801577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
5802577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5803b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    int32_t dataSpace;
5804b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (msg->findInt32("dataspace", &dataSpace)) {
5805b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        status_t err = native_window_set_buffers_data_space(
5806b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
5807b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
5808b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
5809b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
58126aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
581379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
58146fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
5815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
5816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
581790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
581890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
581990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
582090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
582190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
582290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
582390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
582490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5825fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
5826fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
5827c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
5828fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
5829c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar                ALOGV("using buffer PTS of %lld", (long long)timestampNs);
5830fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
5831fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
5832fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
5833fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
58345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
5835fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
58360806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5837fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
583815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
58390806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
584015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
584115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
58420806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
5843cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5844cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
5845264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGE("queueBuffer failed in onOutputBufferDrained: %d", err);
5846251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5847cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
584815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
584915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
5850cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
5851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
58526fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
58536fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
585415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
585515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
58566fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
58576fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
5858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
5859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
5880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
5882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
5883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5887c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
5888609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
5889c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
589015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
589115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(
589215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                            mCodec->mNode, info->mBufferID, info->mFenceFd);
589315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
58940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
58950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
58960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
58970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5899c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5904777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
59060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
59070806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
59080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
59090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5912777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5913777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5914777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5915777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5921f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5925c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
5926c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
5927ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5928ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
592923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mCodec->mNodeBinder->unlinkToDeath(mDeathNotifier);
5930ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5931ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5932ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5933b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    mCodec->mUsingNativeWindow = false;
5934ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
5935e3635355e4cae5af7550b49888c6a0e3530b8aeaLajos Molnar    mCodec->mNativeWindowUsageBits = 0;
5936ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
5937ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
5938ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
5939ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
5940054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
5941054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
5942ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
5943c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5944c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5945f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
59585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
59595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
59605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
59615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
59625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
59635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
5965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5966c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5967c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5968c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
596954b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
597054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
5971c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5973d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5977c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5983d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5987c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
599030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
599130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
599230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
599330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
599430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
599530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
599630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6004f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
6005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
6007c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
6008c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
6009c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
60105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
60115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
60135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
60145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6015ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
60165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
601848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
601948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
602048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
602148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
6022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
6024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
6026ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
6027b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar    Vector<AString> matchingCodecs;
60285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
6030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
6032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
60337791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
60345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
6035b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        sp<IMediaCodecList> list = MediaCodecList::getInstance();
6036b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        if (list != NULL && list->findCodecByName(componentName.c_str()) >= 0) {
6037b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar            matchingCodecs.add(componentName);
6038afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
60395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
60405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
60415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
60425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
60435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
60445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
60455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6046b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        MediaCodecList::findMatchingCodecs(
60475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
60485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
6049b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar                0,       // flags
6050e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
60515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
60521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
60531065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
6054ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
60551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6056201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
60571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
60581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
6059b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        componentName = matchingCodecs[matchIndex];
6060b60521e269e5aeca773853dfeb150e9a512c7334Lajos Molnar        quirks = MediaCodecList::getQuirksFor(componentName.c_str());
6061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6062da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
6063078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
6064078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
606523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        err = omx->allocateNode(componentName.c_str(), observer, &mCodec->mNodeBinder, &node);
6066078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
6067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
60691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
60707a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
60717a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
60721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
60731065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6074ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
60751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
60761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
6077ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
60785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
60799f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
60809f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
60815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
60829f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
60835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6084c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
608552e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
6086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
6087c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
608923858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    mDeathNotifier = new DeathNotifier(notify);
609023858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    if (mCodec->mNodeBinder == NULL ||
609123858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen            mCodec->mNodeBinder->linkToDeath(mDeathNotifier) != OK) {
609223858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // This was a local binder, if it dies so do we, we won't care
609323858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        // about any notifications in the afterlife.
609423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen        mDeathNotifier.clear();
609523858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    }
609623858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen
609726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
6098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
6099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
610190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
6102ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
6103ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6104ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
6105ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
61061713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
61070167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
6108ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
6109ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
6110afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
6111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
6112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
6113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
61145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
61155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6116d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
61175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
61185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
61195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6121c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
6122c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6123c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
61245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
61255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6126c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
6127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
6129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
6130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6132c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
6133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
6134c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6135f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
6136f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
6137f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6138f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
6139f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
6140054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
6141054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
6142a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
6143e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
6144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
61454e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
6146054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
6148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
6149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6150c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
6151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
6152c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6153c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
6154c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
615554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
6156f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
6157f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
6158c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6159c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6160c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
6161c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
61620806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
6163c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6164c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
6165c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6166c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
616754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
616854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
6169d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
617054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
617154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
617254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
6173c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6174c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6175c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
6176c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
6177c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6178c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
6179c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
6180c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6181c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
6182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
61867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
61877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
61887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
61897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
61907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
61917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
61927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
61938f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
6194d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
61958f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
6196d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
6197d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
6198d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
6199d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
6201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6202c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
6203c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6204c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
6208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
621354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
6215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
6221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
6222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6223d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
6225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
6227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
6228c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
6229c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6230c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
6231c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
6232c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
6233c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6234c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
6235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
6236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
62385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
62395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
62405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6241ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
62425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
62430806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
62445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
62450806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
62460806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
62470806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
62480806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
62490806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
62505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
6251c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
6252c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
6253c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
6254251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
62565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
62595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6260d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
6261e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
6262e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
62635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
62645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
62675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
62685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6269d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
6270d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
6271a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6272d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
6273a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
6274a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
6275a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
6276a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
6277a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
6278a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
6279a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6280a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
6281a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
6282a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
6283a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
6284a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
6285d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
6286a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
6287a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
6288a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
6289d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
629094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
629194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
629294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
629394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
629494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
629594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
629694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
629794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
629894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
629972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
630072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
6301d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
63022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
63032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
63042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
6305d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
630637b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
630737b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
630837b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
630937b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
631037b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
631137b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
631237b2b389139ed638831e49708c947863eef631efRonghua Wu
631337b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
631437b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
631537b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
631637b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
6317d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
631837b2b389139ed638831e49708c947863eef631efRonghua Wu        }
631937b2b389139ed638831e49708c947863eef631efRonghua Wu    }
632037b2b389139ed638831e49708c947863eef631efRonghua Wu
6321d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
63222c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
63232c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
63242c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
63252c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
63262c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
63272c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
63282c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
63292c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
63302c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
63312c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
63322c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
63332c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
63342c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
63352c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
63362c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
6337d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
63382c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
63392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
634072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6341d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
634272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
634372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
634472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
634572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
634672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
634772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
634872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
634972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
635072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
635172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
635294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
635394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
6354d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
635594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
635694ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
635794ee4b708acfa941581160b267afb79192b1d816Chong Zhang
6358c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    uint32_t usageBits;
6359c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    if (mCodec->mOMX->getParameter(
6360c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
6361c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            &usageBits, sizeof(usageBits)) == OK) {
6362c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mCodec->mInputFormat->setInt32(
6363c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
6364c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
6365c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    sp<ABuffer> colorAspectsBuffer;
6367b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mCodec->mInputFormat->findBuffer("android._color-aspects", &colorAspectsBuffer)) {
6368b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInternalOption(
6369b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, IOMX::INTERNAL_OPTION_COLOR_ASPECTS,
6370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                colorAspectsBuffer->base(), colorAspectsBuffer->capacity());
6371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (err != OK) {
6372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGE("[%s] Unable to configure color aspects (err %d)",
6373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                  mCodec->mComponentName.c_str(), err);
6374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            return err;
6375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
6376b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6377d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
6378d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6379d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6380d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
6381d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
6382d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
6383d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6384d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6385d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
6386d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6388b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6389b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6390b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6391b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
639257fad3c31f46ec98d15bc253c16f9d269aeb8ea7Lajos Molnar
6393d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
6394b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->createInputSurface(
6396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, dataSpace, &bufferProducer, &mCodec->mInputMetadataType);
6397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6398d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6399d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6400d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6401d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6402d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
64037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
64047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
64057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
64067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
64077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
64087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
64097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
64107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
64117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
64127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
64137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
64147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
64157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
64167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
64178f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
6418d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
64198f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
6420d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6421d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
6422d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
6423d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6424d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
6425d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
6426d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
6427d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
6429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    status_t err =
6430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mCodec->setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(&dataSpace);
6431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("input-format", mCodec->mInputFormat);
6432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    notify->setMessage("output-format", mCodec->mOutputFormat);
6433b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
6434b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (err == OK) {
6435b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        err = mCodec->mOMX->setInputSurface(
6436b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
6437b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                &mCodec->mInputMetadataType);
6438b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
6439d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6440d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
6441b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        surface->getBufferConsumer()->setDefaultBufferDataSpace(dataSpace);
6442d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
6443d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6444d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6445d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
6446d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
6447d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
6448d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
64498f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
6450d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
6451d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
6452d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
6453d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
6454d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
6455d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
6456c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
64575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
64585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
64590806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
64600806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
64610806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
64620806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
64630806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
64640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6469f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
6470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6473f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
64743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
6475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6476cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
6477cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
647829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
6479cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
6480cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
6481cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
6482251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
648391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
6484c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        mCodec->mOMX->sendCommand(
6485c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
6486c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexInput)) {
6487c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexInput);
6488c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6489c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        if (mCodec->allYourBuffersAreBelongToUs(kPortIndexOutput)) {
6490c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia            mCodec->freeBuffersOnPort(kPortIndexOutput);
6491c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia        }
6492c673de8067ad53f96b3fcd2b7b24b066303a32aaWei Jia
649391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
6494cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
6495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6497f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
6498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
6499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
6501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
6502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
6505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6507f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
650972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
65176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
65186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
65196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
65206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
65216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
65226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
65236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
65246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
65256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
65266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
65276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
65286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
65296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
65306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
65316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
6532d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
65336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
65346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
65356463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
65366463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
6537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6542f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
6543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
65470806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
65480806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
65490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
65500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
65510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
65520806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
65530806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
65540806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
65570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
65580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
65590806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65610806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
65620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
65630806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
65640806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
65650806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6577f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
6578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6581f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
65823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
6583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6585f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
658772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
6588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6594d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
6595d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6596d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
6597d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6598d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6599d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6600d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
6601d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
6602d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
6603d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
6604d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6605d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
6606d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
6607d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
6608d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
6609d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
66106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
66116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
66126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
66136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
66146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
66156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
6618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6621f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
6622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
66260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
66270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
66280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
66290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
66300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
66310806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
66320806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
66330806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
6636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
6637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6648f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
6649349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
6650349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
6651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6653f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
6654ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
6655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
6659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
6660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
6661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
6662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
6663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6664054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
6665054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
6666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
6667054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
6668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
66694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
66704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6671054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
66750806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
66800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
66810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
66820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
66830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
66840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
66850806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
66910806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
66920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
66930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
66940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
66950806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66980806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6699349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
670015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
670115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
670215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
67030806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
67040806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
67050806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
67060806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
67100806340688c937e7b78c2d89db3809274130df4eLajos Molnar
67110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
67120806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
67130806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6716054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6717c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6718054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6719054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6720054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6723f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6724349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
67250806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6726349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6727349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6728349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67313cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6732777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6733777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6734777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6735777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
67363cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
67373cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
67383cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
67393cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
67403cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
67413cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6742349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6743349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6746f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
67473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
674990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
6751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6753f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6761c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6762c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
676454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6765c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6767349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6768349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
67690806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
67700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
67710806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
67720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
67730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
67740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
67750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
67760806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
67770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
67780806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
67867a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
6787ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
6788d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
6789d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6790d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
6791d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6792d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
6793d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6794349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6795349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
67960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
67970806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
67980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
67990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
68000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
68010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
6808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
6810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6815496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
6816496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
6817496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
6818496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
6819496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
6820496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
6821496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6822496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
6823496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
6824496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
6825496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6826a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
6827a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
6828a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
6829a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
6830a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6831a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
6832a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6833a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
6834a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
6835a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
6836a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
6837a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
6838a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6839a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
6840a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
6841a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6842a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
68437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
68447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
68456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
68467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
68477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
68487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
68497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
68504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6851054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
68524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
68534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
68544dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
6855054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
68564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
6857054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
68584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
68594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
68604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
68614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
68624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6871a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
6872a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
6873530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
6874a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6875a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
6876a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
6877a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
6878a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6879a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
6880a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
6881a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
6882a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
6883a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
6884a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6885a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
6886a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
6887a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
6888a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6889a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
6890a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6891a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
6892a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
689372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
689472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
689572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
689672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
689772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
689872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
689972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
690072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
690172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
690272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
690372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
690472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
690572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
690672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
690772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
690872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6909e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
6910e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
6911e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
6912e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
6913b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
6914b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
6915e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
6916e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
6917e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
6918e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
6919b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
6920b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6921b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
6922b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
6923b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
6924b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
6925b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
6926b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6927b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
6928b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
6929b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
6930b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6931b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
6932b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
6933b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
6934b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
6935e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
6936e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
69378db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
69388db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
69398db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
69408db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
69418db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
69428db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
69438db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
69448db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
69458db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
6946870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    int32_t intraRefreshPeriod = 0;
6947870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    if (params->findInt32("intra-refresh-period", &intraRefreshPeriod)
6948870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            && intraRefreshPeriod > 0) {
6949870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        status_t err = setIntraRefreshPeriod(intraRefreshPeriod, false);
6950870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        if (err != OK) {
6951870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            ALOGI("[%s] failed setIntraRefreshPeriod. Failure is fine since this key is optional",
6952870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang                    mComponentName.c_str());
6953870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang            err = OK;
6954870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang        }
6955870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang    }
6956870aff9bd2442c8877f5d6b12c73032b5f24535aHangyu Kuang
6957a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
6958a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
6959a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
69606507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
69616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
6962d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
69636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
69646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
69656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
69666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
69676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
69686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
69696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
69706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
697190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
697290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
697390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
697490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
697590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6976f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
6977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
6980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
6982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6983b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            mCodec->onOutputFormatChanged();
6984b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
698531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
6986054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
6987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
6988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
6989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
6990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
6991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6992349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
6993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
6995b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar            } else if (data2 != OMX_IndexConfigCommonOutputCrop
6996b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    && data2 != OMX_IndexConfigAndroidIntraRefresh) {
6997ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
6998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
6999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
7005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7016f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
7017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
7018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7021f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
7022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
7023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
7024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
7025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
7028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
7030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7032f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
7033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7039349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
7040e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
7041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7042349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
70433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
7044349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
7045349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7059f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
70603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
7061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
7062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
706490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
706590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
706690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
706790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
706890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
706990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7070f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
7071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
70760806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
70770806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
70780806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
70790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
7082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
70840806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
70850806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
70860806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
70870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
70880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
70890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
70900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
70930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
70940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
70950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
70980806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
70990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
71000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
71010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
7102cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
71030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
7104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
7105d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7106755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
7107755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
7108755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
7109755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
7110755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
7111755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
7112755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
7113755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
7114cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
7115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
7118777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
7119777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
7120777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7121777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
7124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7125349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
7126349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
7127349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
7128349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
7130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
7132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
7139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7144f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
71455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
71465778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
7147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
7150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
71570806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
7158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7177f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
71783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
717931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
71805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
7181b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar    mCodec->mLastOutputFormat.clear();
7182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7184f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
7185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
71890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
71900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
71910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
71920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
71930806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
71940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
71950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
71960806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
71995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
7201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7205349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7206349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
7207349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
7208349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
7209349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7210349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7211349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
72160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
7217f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
72185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
72190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
72200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
72210806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
72220806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
72230806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
72240806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
72250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
72260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
72270806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
7228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72290167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
72300167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
7231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
7232bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
7233bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
7234bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
7235b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
7236bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
7237bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
72380806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
72390806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
72400806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
72410806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
72420806340688c937e7b78c2d89db3809274130df4eLajos Molnar
7243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
7244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7247f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
7248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7254f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
7255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
7256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7263f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
7264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7267f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
7268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
7274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
7282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
72830806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
7284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7295f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
72963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
7297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7299f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
7300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
73040806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
73050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
73060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
73070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
73080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
73090806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
73110806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
7314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
7324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7325f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
7326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
7327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7329f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
73303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
7331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
7333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7335f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
7336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
7337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
7339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
7340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
7342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
7346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
7347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
7348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
7349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
7354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
7355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
7358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7360f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
7361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
7362ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
7363ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
7364d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
7365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
7366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
7367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
73680806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
73690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
73700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
73710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
73720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
73730806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
7374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
7376777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
7377777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
7378777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
7379777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
7380777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
7382e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
73830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
7384e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
7385e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
7386777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
7387777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
7388777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
7389777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
7390777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
7391777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
7392777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
7393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
7395777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
7396777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
7397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
7398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
7400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
7401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
7403349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
74041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
7405349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
7406609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
7407349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
7408349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
7409349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
7410349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
74113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
7412349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
7413349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7414349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
7415349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7416349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
7417349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
7418349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
7419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
7420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
7421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
7424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7426f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
7427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
7428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7432f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
7433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
7434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
7436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7438f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
7439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
7440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
7441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
74427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
74437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
74447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
74457e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
744690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
744790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
7448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
7449d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
7450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
7451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
7453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
7454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7455dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
7456dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
7457f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
7458f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
7459f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
7460f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
7461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
7462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
7463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
7464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
74655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t ACodec::queryCapabilities(
74665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
74675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps) {
74685b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    (*caps).clear();
74695b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    const char *role = getComponentRole(isEncoder, mime.c_str());
74705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (role == NULL) {
74715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return BAD_VALUE;
74725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
74735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
74745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    OMXClient client;
74755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    status_t err = client.connect();
74765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
74775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
74785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
74795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
74805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<IOMX> omx = client.interface();
74815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecObserver> observer = new CodecObserver;
74825b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    IOMX::node_id node = 0;
74835b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
748423858874bbce68fb5ac83250087fa7788c97dd12Marco Nelissen    err = omx->allocateNode(name.c_str(), observer, NULL, &node);
74855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
74865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
74875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
74885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
74895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
74905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    err = setComponentRole(omx, node, role);
74915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (err != OK) {
74925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        omx->freeNode(node);
74935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        client.disconnect();
74945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return err;
74955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
74965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
74975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<MediaCodecInfo::CapabilitiesBuilder> builder = new MediaCodecInfo::CapabilitiesBuilder();
74985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    bool isVideo = mime.startsWithIgnoreCase("video/");
74995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo) {
75015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
75025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
75035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
75045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75056e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
75066e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
75075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
75085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
75095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
75105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
75115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
75125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
75135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, param.eLevel);
75146e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
75156e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
75166e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x/%x",
75176e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
75186e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile, param.eLevel);
75196e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
75205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
75215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // Color format query
75235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // return colors in the order reported by the OMX component
75245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // prefix "flexible" standard ones with the flexible equivalent
75255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
75265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&portFormat);
752736e4e1592bb07e1fdf8d4324f65a66ba332d75f2Lajos Molnar        portFormat.nPortIndex = isEncoder ? kPortIndexInput : kPortIndexOutput;
75285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        Vector<uint32_t> supportedColors; // shadow copy to check for duplicates
75296e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
75306e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            portFormat.nIndex = index;
75315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
75325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, OMX_IndexParamVideoPortFormat,
75335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &portFormat, sizeof(portFormat));
75345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
75355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
75365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
75375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            OMX_U32 flexibleEquivalent;
75395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (isFlexibleColorFormat(
75405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    omx, node, portFormat.eColorFormat, false /* usingNativeWindow */,
75415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &flexibleEquivalent)) {
75425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                bool marked = false;
75435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                for (size_t i = 0; i < supportedColors.size(); ++i) {
75445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    if (supportedColors[i] == flexibleEquivalent) {
75455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        marked = true;
75465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                        break;
75475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    }
75485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
75495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                if (!marked) {
75505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    supportedColors.push(flexibleEquivalent);
75515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    builder->addColorFormat(flexibleEquivalent);
75525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                }
75535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
75545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            supportedColors.push(portFormat.eColorFormat);
75555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addColorFormat(portFormat.eColorFormat);
75566e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
75576e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
75586e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking formats after %u: %s(%x)",
75596e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
75606e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        asString(portFormat.eColorFormat), portFormat.eColorFormat);
75616e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
75625b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
75635b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (mime.equalsIgnoreCase(MEDIA_MIMETYPE_AUDIO_AAC)) {
75645b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // More audio codecs if they have profiles.
75655b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_AUDIO_PARAM_ANDROID_PROFILETYPE param;
75665b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&param);
75675b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        param.nPortIndex = isEncoder ? kPortIndexOutput : kPortIndexInput;
75686e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar        for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
75696e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            param.nProfileIndex = index;
75705b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            status_t err = omx->getParameter(
75715b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    node, (OMX_INDEXTYPE)OMX_IndexParamAudioProfileQuerySupported,
75725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    &param, sizeof(param));
75735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            if (err != OK) {
75745b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                break;
75755b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            }
75765b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // For audio, level is ignored.
75775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addProfileLevel(param.eProfile, 0 /* level */);
75786e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar
75796e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            if (index == kMaxIndicesToCheck) {
75806e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                ALOGW("[%s] stopping checking profiles after %u: %x",
75816e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        name.c_str(), index,
75826e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar                        param.eProfile);
75836e6d429f8001e831b23c3505824e016a681fcf90Lajos Molnar            }
75845b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
75855b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75865b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // NOTE: Without Android extensions, OMX does not provide a way to query
75875b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // AAC profile support
75885b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (param.nProfileIndex == 0) {
75895b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            ALOGW("component %s doesn't support profile query.", name.c_str());
75905b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
75915b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
75925b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
75935b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && !isEncoder) {
75945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        native_handle_t *sidebandHandle = NULL;
75955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->configureVideoTunnelMode(
75965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE, 0, &sidebandHandle) == OK) {
75975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            // tunneled playback includes adaptive playback
75985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
75995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                    | MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
76005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        } else if (omx->storeMetaDataInBuffers(
76015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE) == OK ||
76025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            omx->prepareForAdaptivePlayback(
76035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, kPortIndexOutput, OMX_TRUE,
76045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                1280 /* width */, 720 /* height */) == OK) {
76055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback);
76065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (isVideo && isEncoder) {
76105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE params;
76115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        InitOMXParams(&params);
76125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        params.nPortIndex = kPortIndexOutput;
76135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        // TODO: should we verify if fallback is supported?
76145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        if (omx->getConfig(
76155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                node, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh,
76165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar                &params, sizeof(params)) == OK) {
76175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar            builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsIntraRefresh);
76185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        }
76195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
76205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
76215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    *caps = builder;
76225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    omx->freeNode(node);
76235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    client.disconnect();
76245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return OK;
76255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
76265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
7627a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// These are supposed be equivalent to the logic in
7628a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar// "audio_channel_out_mask_from_count".
7629a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar//static
7630a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnarstatus_t ACodec::getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {
7631a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    switch (numChannels) {
7632a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 1:
7633a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelCF;
7634a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7635a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 2:
7636a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7637a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7638a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7639a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 3:
7640a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7641a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7642a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7643a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7644a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 4:
7645a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7646a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7647a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelLR;
7648a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelRR;
7649a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7650a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 5:
7651a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7652a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7653a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7654a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLR;
7655a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelRR;
7656a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7657a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 6:
7658a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7659a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7660a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7661a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7662a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7663a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7664a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7665a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 7:
7666a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7667a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7668a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7669a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7670a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7671a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7672a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelCS;
7673a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7674a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        case 8:
7675a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[0] = OMX_AUDIO_ChannelLF;
7676a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[1] = OMX_AUDIO_ChannelRF;
7677a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[2] = OMX_AUDIO_ChannelCF;
7678a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[3] = OMX_AUDIO_ChannelLFE;
7679a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[4] = OMX_AUDIO_ChannelLR;
7680a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[5] = OMX_AUDIO_ChannelRR;
7681a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[6] = OMX_AUDIO_ChannelLS;
7682a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            map[7] = OMX_AUDIO_ChannelRS;
7683a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            break;
7684a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar        default:
7685a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar            return -EINVAL;
7686a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    }
7687a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7688a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar    return OK;
7689a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar}
7690a485208faef579d3d20ee56f29e81d9a5e32e14dLajos Molnar
7691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
7692