ACodec.cpp revision 90fcf68fd29f3cb695bd53a830ad984cb7d430c0
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>
441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
45d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
46b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar#include <media/stagefright/SurfaceUtils.h>
473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
4997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev#include <OMX_VideoExt.h>
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
5297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
53777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim#include <OMX_AsString.h>
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
56496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
57f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// OMX errors are directly mapped into status_t range if
60251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// there is no corresponding MediaError status code.
61251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Use the statusFromOMXError(int32_t omxError) function.
62251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
63251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Currently this is a direct map.
64251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// See frameworks/native/include/media/openmax/OMX_Core.h
65251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
66251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Vendor OMX errors     from 0x90000000 - 0x9000FFFF
67251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Extension OMX errors  from 0x8F000000 - 0x90000000
68251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// Standard OMX errors   from 0x80001000 - 0x80001024 (0x80001024 current)
69251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung//
70251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
71251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// returns true if err is a recognized OMX error code.
72251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// as OMX error is OMX_S32, this is an int32_t type
73251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline bool isOMXError(int32_t err) {
74251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return (ERROR_CODEC_MIN <= err && err <= ERROR_CODEC_MAX);
75251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
76251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
77251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// converts an OMX error to a status_t
78251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t statusFromOMXError(int32_t omxError) {
79251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (omxError) {
80251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorInvalidComponentName:
81251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case OMX_ErrorComponentNotFound:
82251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return NAME_NOT_FOUND; // can trigger illegal argument error for provided names.
83251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
84251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return isOMXError(omxError) ? omxError : 0; // no translation required
85251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
86251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
87251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
88251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung// checks and converts status_t to a non-side-effect status_t
89251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hungstatic inline status_t makeNoSideEffectStatus(status_t err) {
90251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    switch (err) {
91251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // the following errors have side effects and may come
92251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // from other code modules. Remap for safety reasons.
93251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case INVALID_OPERATION:
94251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    case DEAD_OBJECT:
95251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return UNKNOWN_ERROR;
96251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    default:
97251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return err;
98251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
99251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung}
100251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
101f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarstruct MessageList : public RefBase {
11126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    MessageList() {
11226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
11326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > &getList() { return mList; }
11426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarprivate:
11526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    std::list<sp<AMessage> > mList;
11626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
11726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    DISALLOW_EVIL_CONSTRUCTORS(MessageList);
11826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar};
11926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
12826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    virtual void onMessages(const std::list<omx_message> &messages) {
12926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<AMessage> notify;
13026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        bool first = true;
13126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        sp<MessageList> msgList = new MessageList();
13226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        for (std::list<omx_message>::const_iterator it = messages.cbegin();
13326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar              it != messages.cend(); ++it) {
13426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            const omx_message &omx_msg = *it;
13526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            if (first) {
13626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                notify = mNotify->dup();
13726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                notify->setInt32("node", omx_msg.node);
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            sp<AMessage> msg = new AMessage;
14126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msg->setInt32("type", omx_msg.type);
14226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            switch (omx_msg.type) {
14326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EVENT:
14426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
14526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("event", omx_msg.u.event_data.event);
14626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data1", omx_msg.u.event_data.data1);
14726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("data2", omx_msg.u.event_data.data2);
14826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
14926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::EMPTY_BUFFER_DONE:
15226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
15326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
15426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32("fence_fd", omx_msg.fenceFd);
15526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
15626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                case omx_message::FILL_BUFFER_DONE:
15926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                {
16026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
16126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "buffer", omx_msg.u.extended_buffer_data.buffer);
16226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
16326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_offset",
16426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_offset);
16526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
16626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "range_length",
16726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.range_length);
16826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
16926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "flags",
17026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.flags);
17126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt64(
17226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "timestamp",
17326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            omx_msg.u.extended_buffer_data.timestamp);
17426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    msg->setInt32(
17526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                            "fence_fd", omx_msg.fenceFd);
17626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
17726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                }
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case omx_message::FRAME_RENDERED:
18090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
18190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
18290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "media_time_us", omx_msg.u.render_data.timestamp);
18390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    msg->setInt64(
18490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                            "system_nano", omx_msg.u.render_data.nanoTime);
18590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
18690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
18790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
18826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                default:
18926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    ALOGE("Unrecognized message type: %d", omx_msg.type);
19026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar                    break;
19126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            }
19226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            msgList->getList().push_back(msg);
19326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
19426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->setObject("messages", msgList);
19526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        notify->post();
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
23326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles an OMX message. Returns true iff message was handled.
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // Handles a list of messages. Returns true iff messages were handled.
23726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool onOMXMessageList(const sp<AMessage> &msg);
23826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
23926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    // returns true iff this message is for this component and the component is alive
24026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    bool checkOMXMessage(const sp<AMessage> &msg);
24126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
24215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
24815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int64_t timeUs,
24915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd);
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
25290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
261ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
262ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
263ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
264ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
265ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
266ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
267ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
268ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
269ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
270ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
271ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
272ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
273ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
274ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
275ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
276ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
277ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
287c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
290ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
297c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
300c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
301c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
3077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
3088f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    void onSetInputSurface(const sp<AMessage> &msg);
309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
312d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t setupInputSurface();
313d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
316c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
317c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
318c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
353054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
361349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
362349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
36990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
372349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
373349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
38890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual bool onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
418f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
421f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setWriteFence(int fenceFd, const char *dbg) {
45615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
45715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by write fence %d in %s",
45815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
45915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
46015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
46115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = false;
46215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
46315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
46415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::setReadFence(int fenceFd, const char *dbg) {
46515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0) {
46615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW("OVERWRITE OF %s fence %d by read fence %d in %s",
46715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                mIsReadFence ? "read" : "write", mFenceFd, fenceFd, dbg);
46815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
46915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mFenceFd = fenceFd;
47015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    mIsReadFence = true;
47115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
47215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
47315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkWriteFence(const char *dbg) {
47415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && mIsReadFence) {
47515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING read fence %d as write fence in %s", mFenceFd, dbg);
47615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
47715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
47815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
47915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarvoid ACodec::BufferInfo::checkReadFence(const char *dbg) {
48015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mFenceFd >= 0 && !mIsReadFence) {
48115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGD("REUSING write fence %d as read fence in %s", mFenceFd, dbg);
48215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
48315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
48415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
48515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar////////////////////////////////////////////////////////////////////////////////
48615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
487f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
488afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
489609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mNode(0),
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
4918db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu      mIsVideo(false),
492c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
4939806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
49454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar      mExplicitShutdown(false),
4959806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
4969806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
497e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang      mRotationDegrees(0),
4989806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
499054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
500054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
501054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mInputMetadataType(kMetadataBufferTypeInvalid),
502054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mOutputMetadataType(kMetadataBufferTypeInvalid),
503011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar      mLegacyAdaptiveExperiment(false),
504054219874873b41f1c815552987c10465c34ba2bLajos Molnar      mMetadataBuffersToSubmit(0),
50594ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
5062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
50737b2b389139ed638831e49708c947863eef631efRonghua Wu      mMaxFps(-1),
5082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
509609b815a3131d22da38b2f452faa9f89daad4039Andy Hung      mTimePerCaptureUs(-1ll),
510ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mCreateInputBuffersSuspended(false),
511ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad      mTunneled(false) {
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
526dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
531f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
534f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
538f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
5401d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
5451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
546a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
547a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
548a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
549a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
5521d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5565778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
5581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    msg->setTarget(this);
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setSurface(const sp<Surface> &surface) {
5631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
5671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = msg->postAndAwaitResponse(&response);
5681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
5701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)response->findInt32("err", &err);
5711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
5721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
5731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
5741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
5761d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatCreateInputSurface, this))->post();
5777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5798f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::initiateSetInputSurface(
580d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
5818f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
582d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface);
583d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->post();
584d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
585d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
5871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatSignalEndOfInputStream, this))->post();
5887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5905778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
5911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStart, this))->post();
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
594f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
5957a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
5961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatFlush, this))->post();
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
599f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
6001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
603c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
6041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatShutdown, this);
605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
60730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    if (!keepComponentAllocated) {
60830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        // ensure shutdown completes in 3 seconds
6091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        (new AMessage(kWhatReleaseCodecInstance, this))->post(3000000);
61030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar    }
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
613496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
6141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
615496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
616496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6174dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6184dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
6194dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
6204dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
6214dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
622054219874873b41f1c815552987c10465c34ba2bLajos Molnarvoid ACodec::signalSubmitOutputMetadataBufferIfEOS_workaround() {
6234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
624054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mMetadataBuffersToSubmit > 0) {
625054219874873b41f1c815552987c10465c34ba2bLajos Molnar        (new AMessage(kWhatSubmitOutputMetadataBufferIfEOS, this))->post();
6264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
6274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
6284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::handleSetSurface(const sp<Surface> &surface) {
6301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface == NULL) {
6321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (mNativeWindow != NULL) {
6331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("cannot unset a surface");
6341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return INVALID_OPERATION;
6351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
6361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // allow keeping unset surface
6401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mNativeWindow == NULL) {
6411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("component was not configured with a surface");
6421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ANativeWindow *nativeWindow = surface.get();
6461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // if we have not yet started the codec, we can simply set the native window
6471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mBuffers[kPortIndexInput].size() == 0) {
6481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        mNativeWindow = surface;
6491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return OK;
6501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we do not support changing a tunneled surface after start
6531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mTunneled) {
6541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("cannot change tunneled surface");
6551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return INVALID_OPERATION;
6561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = setupNativeWindowSizeFormatAndUsage(nativeWindow);
6591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
6601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // get min undequeued count. We cannot switch to a surface that has a higher
6641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // undequeued count than we allocated.
6651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int minUndequeuedBuffers = 0;
6661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = nativeWindow->query(
6671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
6681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            &minUndequeuedBuffers);
6691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
6711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                strerror(-err), -err);
6721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (minUndequeuedBuffers > (int)mNumUndequeuedBuffers) {
6751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("new surface holds onto more buffers (%d) than planned for (%zu)",
6761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                minUndequeuedBuffers, mNumUndequeuedBuffers);
6771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return BAD_VALUE;
6781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // we cannot change the number of output buffers while OMX is running
6811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // set up surface to the same count
6821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    Vector<BufferInfo> &buffers = mBuffers[kPortIndexOutput];
6831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("setting up surface for %zu buffers", buffers.size());
6841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
6851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = native_window_set_buffer_count(nativeWindow, buffers.size());
6861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
6871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
6881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                -err);
6891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
6901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
6911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
692dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // need to enable allocation when attaching
693dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    surface->getIGraphicBufferProducer()->allowAllocation(true);
694dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
6951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for meta data mode, we move dequeud buffers to the new surface.
6961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // for non-meta mode, we must move all registered buffers
6971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    for (size_t i = 0; i < buffers.size(); ++i) {
6981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        const BufferInfo &info = buffers[i];
6991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // skip undequeued buffers for meta data mode
700054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()
701011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                && !mLegacyAdaptiveExperiment
7021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                && info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGV("skipping buffer %p", info.mGraphicBuffer->getNativeBuffer());
7041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            continue;
7051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGV("attaching buffer %p", info.mGraphicBuffer->getNativeBuffer());
7071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = surface->attachBuffer(info.mGraphicBuffer->getNativeBuffer());
7091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err != OK) {
7101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("failed to attach buffer %p to the new surface: %s (%d)",
7111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    info.mGraphicBuffer->getNativeBuffer(),
7121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    strerror(-err), -err);
7131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            return err;
7141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    // cancel undequeued buffers to new surface
718054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
7191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        for (size_t i = 0; i < buffers.size(); ++i) {
72015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            BufferInfo &info = buffers.editItemAt(i);
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                ALOGV("canceling buffer %p", info.mGraphicBuffer->getNativeBuffer());
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                err = nativeWindow->cancelBuffer(
72415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        nativeWindow, info.mGraphicBuffer->getNativeBuffer(), info.mFenceFd);
72515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                if (err != OK) {
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    ALOGE("failed to cancel buffer %p to the new surface: %s (%d)",
7281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            info.mGraphicBuffer->getNativeBuffer(),
7291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            strerror(-err), -err);
7301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    return err;
7311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
7321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
7331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
7341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // disallow further allocation
7351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)surface->getIGraphicBufferProducer()->allowAllocation(false);
7361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
7371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
738484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    // push blank buffers to previous window if requested
739484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    if (mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown) {
740484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar        pushBlankBuffersToNativeWindow(mNativeWindow.get());
741484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar    }
742484979b1ab25aa41f503bd846323ab93b46d37e5Lajos Molnar
7431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    mNativeWindow = nativeWindow;
7441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return OK;
7451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
755054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers()) {
756054219874873b41f1c815552987c10465c34ba2bLajos Molnar            err = allocateOutputMetadataBuffers();
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
769054219874873b41f1c815552987c10465c34ba2bLajos Molnar            MetadataBufferType type =
770054219874873b41f1c815552987c10465c34ba2bLajos Molnar                portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
771054219874873b41f1c815552987c10465c34ba2bLajos Molnar            int32_t bufSize = def.nBufferSize;
772054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (type == kMetadataBufferTypeGrallocSource) {
773054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoGrallocMetadata);
774054219874873b41f1c815552987c10465c34ba2bLajos Molnar            } else if (type == kMetadataBufferTypeANWBuffer) {
775054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = sizeof(VideoNativeMetadata);
776054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
777054219874873b41f1c815552987c10465c34ba2bLajos Molnar
778054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // If using gralloc or native source input metadata buffers, allocate largest
779054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // metadata size as we prefer to generate native source metadata, but component
780054219874873b41f1c815552987c10465c34ba2bLajos Molnar            // may require gralloc source.
781054219874873b41f1c815552987c10465c34ba2bLajos Molnar            int32_t allottedSize = bufSize;
782054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (portIndex == kPortIndexInput && type > 0) {
783054219874873b41f1c815552987c10465c34ba2bLajos Molnar                bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
784054219874873b41f1c815552987c10465c34ba2bLajos Molnar            }
785054219874873b41f1c815552987c10465c34ba2bLajos Molnar
786054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port",
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
788054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
791054219874873b41f1c815552987c10465c34ba2bLajos Molnar            size_t totalSize = def.nBufferCountActual * bufSize;
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794054219874873b41f1c815552987c10465c34ba2bLajos Molnar            for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
795054219874873b41f1c815552987c10465c34ba2bLajos Molnar                sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
7965581770ee0dde70e2e9c50533be35e537a5800efChong Zhang                if (mem == NULL || mem->pointer() == NULL) {
797777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return NO_MEMORY;
798777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
800ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
801ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
80215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info.mFenceFd = -1;
80390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                info.mRenderInfo = NULL;
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
805afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
806afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
807afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
808afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
8091065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
810308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
811054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        || (portIndex == kPortIndexOutput && usingMetadataOnEncoderOutput())) {
812ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
813ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
814ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
815ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
816054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, bufSize, &info.mBufferID,
817ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
818ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
819308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
820ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
822054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mNode, portIndex, mem, &info.mBufferID, allottedSize);
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
824054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID, allottedSize);
825ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
826ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
827ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
828054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    info.mData = new ABuffer(mem->pointer(), bufSize);
829054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (type == kMetadataBufferTypeANWBuffer) {
830054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
831054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    }
8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
8351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
8361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
844d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
847eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
848eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
849eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
851eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
853eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
856eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
8585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::setupNativeWindowSizeFormatAndUsage(ANativeWindow *nativeWindow /* nonnull */) {
8631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
8641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
8651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
8661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
8681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
8691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
8711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
8721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_U32 usage = 0;
8751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
8761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != 0) {
8771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        ALOGW("querying usage flags from OMX IL component failed: %d", err);
8781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // XXX: Currently this error is logged, but not fatal.
8791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage = 0;
8801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    int omxUsage = usage;
8821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mFlags & kFlagIsGrallocUsageProtected) {
8841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        usage |= GRALLOC_USAGE_PROTECTED;
8851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
8861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
887b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar    usage |= GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP;
888b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar
8891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
8901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return setNativeWindowSizeFormatAndUsage(
8911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            nativeWindow,
8921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameWidth,
8931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.nFrameHeight,
8941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            def.format.video.eColorFormat,
8951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mRotationDegrees,
8961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            usage);
8971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
8981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
8991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
9001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
9011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        OMX_U32 *minUndequeuedBuffers) {
9021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    OMX_PARAM_PORTDEFINITIONTYPE def;
9031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    InitOMXParams(&def);
9041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    def.nPortIndex = kPortIndexOutput;
9051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = mOMX->getParameter(
9071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
9081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
9091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err == OK) {
9101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = setupNativeWindowSizeFormatAndUsage(mNativeWindow.get());
9111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (err != OK) {
9131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        return err;
9141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
9151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
916ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // Exits here for tunneled video playback codecs -- i.e. skips native window
917ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // buffer allocation step as this is managed by the tunneled OMX omponent
918ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    // itself and explicitly sets def.nBufferCountActual to 0.
919ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
920ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGV("Tunneled Playback: skipping native window buffer allocation.");
921ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        def.nBufferCountActual = 0;
922ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        err = mOMX->setParameter(
923ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
924ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
925ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *minUndequeuedBuffers = 0;
926ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferCount = 0;
927ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        *bufferSize = 0;
928ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return err;
929ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
930ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
931054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
932258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
933258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
934054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
935258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
936258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
93729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
938258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
939258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
940258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
941258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
942e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
943e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
9441faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
9451faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
946e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
947e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
948e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
949e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
950e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
951e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
952e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
9531faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
9541faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
955e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
956e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
957258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
958258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
959258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
960258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
961e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
962e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
963e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
964e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
965e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
966609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
967e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
968e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
969e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
970258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
971258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
972258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
973258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
97829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
983054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
984054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
985054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
986054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
987054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
989054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
990054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
991054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
992054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
993054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
994e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
995054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
996054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
9973298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
9983298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(true);
9993298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10003298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1001609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
1003054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
1006054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
10078ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
100815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd;
100915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
101129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
101674006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
101774006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
101815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = fenceFd;
101915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mIsReadFence = false;
102090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1021054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
102274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
102374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
102474006804065941841883c4b46ee785070164023fJamie Gennis
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
1029609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
103074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
103474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
103574006804065941841883c4b46ee785070164023fJamie Gennis
1036609b815a3131d22da38b2f452faa9f89daad4039Andy Hung        ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
104874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
1050054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
1051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
1052054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
10573fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        status_t error = cancelBufferToNativeWindow(info);
10583fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        if (err == 0) {
10593fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            err = error;
10603fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia        }
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1063054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (!storingMetadataInDecodedBuffers()) {
10643298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia        static_cast<Surface*>(mNativeWindow.get())
10653298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia                ->getIGraphicBufferProducer()->allowAllocation(false);
10663298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia    }
10673298d6fa642c11c5b004bdfc375252ff4c4536e3Wei Jia
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1071054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::allocateOutputMetadataBuffers() {
1072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
1073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
1074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
1075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
1076054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
1077e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
1078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1079e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    ALOGV("[%s] Allocating %u meta buffers on output port",
1080e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar         mComponentName.c_str(), bufferCount);
1081e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1082054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
1083054219874873b41f1c815552987c10465c34ba2bLajos Molnar            sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
1084054219874873b41f1c815552987c10465c34ba2bLajos Molnar    size_t totalSize = bufferCount * bufSize;
1085e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
1086e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1087e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    // Dequeue buffers and send them to OMX
1088e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
1089e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        BufferInfo info;
1090e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
109115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info.mFenceFd = -1;
109290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info.mRenderInfo = NULL;
1093e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mGraphicBuffer = NULL;
1094e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mDequeuedAt = mDequeueCounter;
1095e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1096054219874873b41f1c815552987c10465c34ba2bLajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
10975581770ee0dde70e2e9c50533be35e537a5800efChong Zhang        if (mem == NULL || mem->pointer() == NULL) {
1098777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return NO_MEMORY;
1099777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1100054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1101054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
1102054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1103e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
1104e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1105e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // we use useBuffer for metadata regardless of quirks
1106e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        err = mOMX->useBuffer(
1107cc7cc67349b7a3f498882087aa42ffc05a2daf11Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
1108e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1109e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        mBuffers[kPortIndexOutput].push(info);
1110e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1111e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
1112e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
1113e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar    }
1114e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1115011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    if (mLegacyAdaptiveExperiment) {
1116e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar        // preallocate and preregister buffers
1117011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface *>(mNativeWindow.get())
1118011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(true);
1119011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1120011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
1121011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             "output port",
1122011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar             mComponentName.c_str(), bufferCount, bufferSize);
1123011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1124011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        // Dequeue buffers then cancel them all
1125011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < bufferCount; i++) {
1126e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1127e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar
1128011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            ANativeWindowBuffer *buf;
112915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int fenceFd;
113015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
1131011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err != 0) {
1132011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
1133011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                break;
1134011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1135011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1136011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
1137e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            mOMX->updateGraphicBufferInMeta(
1138e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar                    mNode, kPortIndexOutput, graphicBuffer, info->mBufferID);
1139e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mStatus = BufferInfo::OWNED_BY_US;
114015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
1141e66c5a42f01e2f445857b54a9d7bbb8ee062edebLajos Molnar            info->mGraphicBuffer = graphicBuffer;
1142011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1143011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1144011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
1145011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1146011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t error = cancelBufferToNativeWindow(info);
1147011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            if (err == OK) {
1148011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                err = error;
1149011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            }
1150011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        }
1151011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1152011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar        static_cast<Surface*>(mNativeWindow.get())
1153011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ->getIGraphicBufferProducer()->allowAllocation(false);
1154011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    }
1155011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
1156054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
1157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1159054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1160054219874873b41f1c815552987c10465c34ba2bLajos Molnarstatus_t ACodec::submitOutputMetadataBuffer() {
1161054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1162054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mMetadataBuffersToSubmit == 0)
1163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
11660806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (info == NULL) {
1167054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
11680806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
1169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1170609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1173054219874873b41f1c815552987c10465c34ba2bLajos Molnar    --mMetadataBuffersToSubmit;
117415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("submitOutputMetadataBuffer");
117515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t err = mOMX->fillBuffer(mNode, info->mBufferID, info->mFenceFd);
117615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1177777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
1178777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
1179777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
1180054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1181777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
1183054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
118415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarstatus_t ACodec::waitForFence(int fd, const char *dbg ) {
118515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    status_t res = OK;
118615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (fd >= 0) {
118715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        sp<Fence> fence = new Fence(fd);
118815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        res = fence->wait(IOMX::kFenceTimeoutMs);
118915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ALOGW_IF(res != OK, "FENCE TIMEOUT for %d in %s", fd, dbg);
119015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
119115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    return res;
119215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar}
119315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
11940806340688c937e7b78c2d89db3809274130df4eLajos Molnar// static
11950806340688c937e7b78c2d89db3809274130df4eLajos Molnarconst char *ACodec::_asString(BufferInfo::Status s) {
11960806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (s) {
11970806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:            return "OUR";
11980806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_COMPONENT:     return "COMPONENT";
11990806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_UPSTREAM:      return "UPSTREAM";
12000806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_DOWNSTREAM:    return "DOWNSTREAM";
12010806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW: return "SURFACE";
12020806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::UNRECOGNIZED:           return "UNRECOGNIZED";
12030806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:                                 return "?";
12040806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
12050806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
12060806340688c937e7b78c2d89db3809274130df4eLajos Molnar
12070806340688c937e7b78c2d89db3809274130df4eLajos Molnarvoid ACodec::dumpBuffers(OMX_U32 portIndex) {
12080806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
12090806340688c937e7b78c2d89db3809274130df4eLajos Molnar    ALOGI("[%s] %s port has %zu buffers:", mComponentName.c_str(),
12100806340688c937e7b78c2d89db3809274130df4eLajos Molnar            portIndex == kPortIndexInput ? "input" : "output", mBuffers[portIndex].size());
12110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
12120806340688c937e7b78c2d89db3809274130df4eLajos Molnar        const BufferInfo &info = mBuffers[portIndex][i];
12130806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGI("  slot %2zu: #%8u %p/%p %s(%d) dequeued:%u",
12140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                i, info.mBufferID, info.mGraphicBuffer.get(),
12150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                info.mGraphicBuffer == NULL ? NULL : info.mGraphicBuffer->getNativeBuffer(),
12160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                _asString(info.mStatus), info.mStatus, info.mDequeuedAt);
12170806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
12180806340688c937e7b78c2d89db3809274130df4eLajos Molnar}
12190806340688c937e7b78c2d89db3809274130df4eLajos Molnar
1220f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1223609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] Calling cancelBuffer on buffer %u",
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
122615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->checkWriteFence("cancelBufferToNativeWindow");
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
122815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
122915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->mFenceFd = -1;
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12313fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    ALOGW_IF(err != 0, "[%s] can not return buffer %u to native window",
12323fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia            mComponentName.c_str(), info->mBufferID);
12330806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // change ownership even if cancelBuffer fails
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
1235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12363fb9f68dea5d991288f0ea8037742b50c7df5767Wei Jia    return err;
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::updateRenderInfoForDequeuedBuffer(
124090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ANativeWindowBuffer *buf, int fenceFd, BufferInfo *info) {
124190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
124290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo =
124390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.updateInfoForDequeuedBuffer(
124490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                buf, fenceFd, info - &mBuffers[kPortIndexOutput][0]);
124590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
124690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // check for any fences already signaled
124790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    notifyOfRenderedFrames(false /* dropIncomplete */, info->mRenderInfo);
124890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
124990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
125090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::onFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
125190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (mRenderTracker.onFrameRendered(mediaTimeUs, systemNano) != OK) {
125290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.dumpRenderQueue();
125390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
125490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
125590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
125690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid ACodec::notifyOfRenderedFrames(bool dropIncomplete, FrameRenderTracker::Info *until) {
125790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = mNotify->dup();
125890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setInt32("what", CodecBase::kWhatOutputFramesRendered);
125990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    std::list<FrameRenderTracker::Info> done =
126090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.checkFencesAndGetRenderedFrames(until, dropIncomplete);
126190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
126290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // unlink untracked frames
126390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
126490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
126590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (it->getIndex() >= 0) {
126690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mBuffers[kPortIndexOutput].editItemAt(it->getIndex()).mRenderInfo = NULL;
126790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
126890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
126990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
127090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (MediaCodec::CreateFramesRenderedMessage(done, msg)) {
127190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->post();
127290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
127390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
127490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1275f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
12768ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
1277054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
1278ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
1279ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    if (mTunneled) {
1280ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        ALOGW("dequeueBufferFromNativeWindow() should not be called in tunnel"
1281ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad              " video playback mode mode!");
1282ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad        return NULL;
1283ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad    }
1284ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
128515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    int fenceFd = -1;
1286dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    do {
128715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
128815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (err != 0) {
128915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGE("dequeueBuffer failed: %s(%d).", asString(err), err);
1290dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            return NULL;
1291dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1293dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        bool stale = false;
1294dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1295dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
1296dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar
1297dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            if (info->mGraphicBuffer != NULL &&
129890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    info->mGraphicBuffer->handle == buf->handle) {
1299dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // Since consumers can attach buffers to BufferQueues, it is possible
1300dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // that a known yet stale buffer can return from a surface that we
1301dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // once used.  We can simply ignore this as we have already dequeued
1302dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // this buffer properly.  NOTE: this does not eliminate all cases,
1303dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // e.g. it is possible that we have queued the valid buffer to the
1304dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // NW, and a stale copy of the same buffer gets dequeued - which will
1305dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                // be treated as the valid buffer by ACodec.
1306dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                if (info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
1307dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    ALOGI("dequeued stale buffer %p. discarding", buf);
1308dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    stale = true;
1309dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                    break;
1310dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                }
131190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1312dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                ALOGV("dequeued buffer %p", info->mGraphicBuffer->getNativeBuffer());
1313dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                info->mStatus = BufferInfo::OWNED_BY_US;
131415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow");
131590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                updateRenderInfoForDequeuedBuffer(buf, fenceFd, info);
1316dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar                return info;
1317dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            }
1318dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1320dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // It is also possible to receive a previously unregistered buffer
1321dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // in non-meta mode. These should be treated as stale buffers. The
1322dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // same is possible in meta mode, in which case, it will be treated
1323dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // as a normal buffer, which is not desirable.
1324dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        // TODO: fix this.
1325054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
1326dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
1327dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            stale = true;
1328dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        }
1329dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        if (stale) {
1330dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            // TODO: detach stale buffer, but there is no API yet to do it.
1331dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            buf = NULL;
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1333dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    } while (buf == NULL);
1334054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1335dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    // get oldest undequeued buffer
1336dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    BufferInfo *oldest = NULL;
1337dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1338dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar        BufferInfo *info =
1339dd248abd2c3e5e82b0049d40c7e9fb741fd4540cLajos Molnar            &mBuffers[kPortIndexOutput].editItemAt(i);
1340054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
1341054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
1342054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
1343054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
1344054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
1345054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
1346054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1347054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1348054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
13490806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible dequeue a buffer when there are no buffers with ANW
13500806340688c937e7b78c2d89db3809274130df4eLajos Molnar    CHECK(oldest != NULL);
13510806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // it is impossible to dequeue an unknown buffer in non-meta mode, as the
13520806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // while loop above does not complete
1353054219874873b41f1c815552987c10465c34ba2bLajos Molnar    CHECK(storingMetadataInDecodedBuffers());
1354054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
13550806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // discard buffer in LRU info and replace with new buffer
13560806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
13570806340688c937e7b78c2d89db3809274130df4eLajos Molnar    oldest->mStatus = BufferInfo::OWNED_BY_US;
135815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    oldest->setWriteFence(fenceFd, "dequeueBufferFromNativeWindow for oldest");
135990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(oldest->mRenderInfo);
136090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    oldest->mRenderInfo = NULL;
1361d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
13620806340688c937e7b78c2d89db3809274130df4eLajos Molnar    mOMX->updateGraphicBufferInMeta(
13630806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mNode, kPortIndexOutput, oldest->mGraphicBuffer,
13640806340688c937e7b78c2d89db3809274130df4eLajos Molnar            oldest->mBufferID);
1365054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1366054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
1367054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoGrallocMetadata *grallocMeta =
1368054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoGrallocMetadata *>(oldest->mData->base());
1369054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1370054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1371054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
13729847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar                grallocMeta->pHandle,
1373054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
1374054219874873b41f1c815552987c10465c34ba2bLajos Molnar    } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
1375054219874873b41f1c815552987c10465c34ba2bLajos Molnar        VideoNativeMetadata *nativeMeta =
1376054219874873b41f1c815552987c10465c34ba2bLajos Molnar            reinterpret_cast<VideoNativeMetadata *>(oldest->mData->base());
1377054219874873b41f1c815552987c10465c34ba2bLajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
1378054219874873b41f1c815552987c10465c34ba2bLajos Molnar                (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
1379054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
1380054219874873b41f1c815552987c10465c34ba2bLajos Molnar                nativeMeta->pBuffer,
1381054219874873b41f1c815552987c10465c34ba2bLajos Molnar                oldest->mGraphicBuffer->getNativeBuffer(), oldest->mData->base());
1382054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
13850806340688c937e7b78c2d89db3809274130df4eLajos Molnar    return oldest;
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
1389777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
1391777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err2 = freeBuffer(portIndex, i);
1392777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
1393777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            err = err2;
1394777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13970806340688c937e7b78c2d89db3809274130df4eLajos Molnar    // clear mDealer even on an error
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
1399777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
1403777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = OK;
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14082ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
14092ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
14102ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
14112ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
1412777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            status_t err2 = freeBuffer(kPortIndexOutput, i);
1413777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            if (err == OK) {
1414777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                err = err2;
1415777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            }
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1419777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
14240806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // there should not be any fences in the metadata
142715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    MetadataBufferType type =
142815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
142915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (type == kMetadataBufferTypeANWBuffer && info->mData != NULL
143015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            && info->mData->size() >= sizeof(VideoNativeMetadata)) {
143115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd = ((VideoNativeMetadata *)info->mData->data())->nFenceFd;
143215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
143315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ALOGW("unreleased fence (%d) in %s metadata buffer %zu",
143415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd, portIndex == kPortIndexInput ? "input" : "output", i);
143515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
143615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
143715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
14380806340688c937e7b78c2d89db3809274130df4eLajos Molnar    switch (info->mStatus) {
14390806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_US:
14400806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (portIndex == kPortIndexOutput && mNativeWindow != NULL) {
14410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                (void)cancelBufferToNativeWindow(info);
14420806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
14430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            // fall through
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14450806340688c937e7b78c2d89db3809274130df4eLajos Molnar        case BufferInfo::OWNED_BY_NATIVE_WINDOW:
14460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mOMX->freeBuffer(mNode, portIndex, info->mBufferID);
14470806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
14480806340688c937e7b78c2d89db3809274130df4eLajos Molnar
14490806340688c937e7b78c2d89db3809274130df4eLajos Molnar        default:
14500806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("trying to free buffer not owned by us or ANW (%d)", info->mStatus);
14510806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = FAILED_TRANSACTION;
14520806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
145515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (info->mFenceFd >= 0) {
145615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        ::close(info->mFenceFd);
145715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
145815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
145990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.untrackFrame(info->mRenderInfo);
146090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    info->mRenderInfo = NULL;
146190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1462777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    // remove buffer even if mOMX->freeBuffer fails
1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1465777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    return err;
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1468f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
14690806340688c937e7b78c2d89db3809274130df4eLajos Molnar        uint32_t portIndex, IOMX::buffer_id bufferID, ssize_t *index) {
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1481777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    ALOGE("Could not find buffer with ID %u", bufferID);
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
1490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
1494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
1495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
14962944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
14972944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
14982944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
14992944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
1504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
1505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
1506729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
1507729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
1508bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
1509bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
1510c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
1511c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
1512c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
1513c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
1514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
1515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
15162472b1c0d63454e5d90a982bd6c555de6c3127bdRachad        { MEDIA_MIMETYPE_VIDEO_HEVC,
15172472b1c0d63454e5d90a982bd6c555de6c3127bdRachad            "video_decoder.hevc", "video_encoder.hevc" },
1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
152294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
152394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
152494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
152594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1526ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1527ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
15282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
15292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1530ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1531ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1532774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1533774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
153497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
153597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
15368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        { MEDIA_MIMETYPE_AUDIO_EAC3,
15378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            "audio_decoder.eac3", "audio_encoder.eac3" },
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
15725ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1589e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
15904e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> outputFormat = mNotify->dup(); // will use this for kWhatOutputFormatChanged
1591e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1594054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mInputMetadataType = kMetadataBufferTypeInvalid;
1595054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mOutputMetadataType = kMetadataBufferTypeInvalid;
15968db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
16042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
16052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
16062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1611d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1614054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
1615d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1616054219874873b41f1c815552987c10465c34ba2bLajos Molnar            ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1617308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1618d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1619054219874873b41f1c815552987c10465c34ba2bLajos Molnar            return err;
1620054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1621054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // For this specific case we could be using camera source even if storeMetaDataInBuffers
1622054219874873b41f1c815552987c10465c34ba2bLajos Molnar        // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
1623054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
1624054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mInputMetadataType = kMetadataBufferTypeCameraSource;
1625054219874873b41f1c815552987c10465c34ba2bLajos Molnar        }
1626054219874873b41f1c815552987c10465c34ba2bLajos Molnar    }
1627d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1628308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
16293a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
16303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
16313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
16323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
16333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
16343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
16353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
16363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
16373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
16393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
16403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
16413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
16423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
16443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
16453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
16463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
16483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
16493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
16503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
16513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
16523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
16533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
16543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1655308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1656308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1657308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1658308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
16598db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    mIsVideo = video;
1660308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1661308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1662308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1663308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1664308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1665054219874873b41f1c815552987c10465c34ba2bLajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
1666308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1667308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1668308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1669308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1670a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1671a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1672a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1673a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1674a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1675a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
167694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
167794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
16782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
16792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
16802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
168137b2b389139ed638831e49708c947863eef631efRonghua Wu        if (!msg->findFloat("max-fps-to-encoder", &mMaxFps)) {
168237b2b389139ed638831e49708c947863eef631efRonghua Wu            mMaxFps = -1;
168337b2b389139ed638831e49708c947863eef631efRonghua Wu        }
168437b2b389139ed638831e49708c947863eef631efRonghua Wu
16852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
16862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
168794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
168872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
168972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
169072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
169172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
169272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
169372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1694308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1695308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
16963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    // NOTE: we only use native window for video decoders
1697054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
16980d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    bool haveNativeWindow = msg->findObject("native-window", &obj)
16993a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            && obj != NULL && video && !encoder;
1700011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar    mLegacyAdaptiveExperiment = false;
1701e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1702e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
17031713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang
17041713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        int32_t usageProtected;
17051713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        if (msg->findInt32("protected", &usageProtected) && usageProtected) {
17061713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            if (!haveNativeWindow) {
17071713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                ALOGE("protected output buffers must be sent to an ANativeWindow");
17081713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang                return PERMISSION_DENIED;
17091713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            }
17101713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagIsGrallocUsageProtected;
17111713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
17121713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        }
1713e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
17143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar    if (haveNativeWindow) {
17151de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar        sp<ANativeWindow> nativeWindow =
17161de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            static_cast<ANativeWindow *>(static_cast<Surface *>(obj.get()));
17175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17186597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // START of temporary support for automatic FRC - THIS WILL BE REMOVED
17196597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        int32_t autoFrc;
17206597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        if (msg->findInt32("auto-frc", &autoFrc)) {
17216597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            bool enabled = autoFrc;
17226597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            OMX_CONFIG_BOOLEANTYPE config;
17236597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            InitOMXParams(&config);
17246597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            config.bEnabled = (OMX_BOOL)enabled;
17256597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            status_t temp = mOMX->setConfig(
17266597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    mNode, (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion,
17276597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                    &config, sizeof(config));
17286597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            if (temp == OK) {
17296597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                outputFormat->setInt32("auto-frc", enabled);
17306597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            } else if (enabled) {
17316597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar                ALOGI("codec does not support requested auto-frc (err %d)", temp);
17326597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar            }
17336597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        }
17346597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar        // END of temporary support for automatic FRC
17356597c00f7015e5ec9a07601d7a760169ca7266d3Lajos Molnar
17365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        int32_t tunneled;
17375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        if (msg->findInt32("feature-tunneled-playback", &tunneled) &&
17385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            tunneled != 0) {
17395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            ALOGI("Configuring TUNNELED video playback.");
1740ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = true;
17415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
174297827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            int32_t audioHwSync = 0;
174397827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad            if (!msg->findInt32("audio-hw-sync", &audioHwSync)) {
17445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGW("No Audio HW Sync provided for video tunnel");
17455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
17465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = configureTunneledVideoPlayback(audioHwSync, nativeWindow);
17475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
174897827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad                ALOGE("configureTunneledVideoPlayback(%d,%p) failed!",
17495a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        audioHwSync, nativeWindow.get());
17505a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                return err;
1751fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1752fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1753d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            int32_t maxWidth = 0, maxHeight = 0;
1754d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            if (msg->findInt32("max-width", &maxWidth) &&
1755d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    msg->findInt32("max-height", &maxHeight)) {
1756d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad
1757d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                err = mOMX->prepareForAdaptivePlayback(
1758d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1759d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                if (err != OK) {
1760d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    ALOGW("[%s] prepareForAdaptivePlayback failed w/ err %d",
1761d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                            mComponentName.c_str(), err);
17623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // allow failure
17633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    err = OK;
1764d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                } else {
1765d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-width", maxWidth);
1766d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("max-height", maxHeight);
1767d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                    inputFormat->setInt32("adaptive-playback", true);
1768d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad                }
1769d0b9a2b8538c9e4538d92fd675cf6786644ccb85Rachad            }
17705a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        } else {
1771ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            ALOGV("Configuring CPU controlled video playback.");
1772ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad            mTunneled = false;
1773ab76066c11e988ca3d3a5d6d74dd510ae080322eRachad
17743fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // Explicity reset the sideband handle of the window for
17753fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // non-tunneled video in case the window was previously used
17763fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            // for a tunneled video playback.
17773fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            err = native_window_set_sideband_stream(nativeWindow.get(), NULL);
17783fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            if (err != OK) {
17793fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                ALOGE("set_sideband_stream(NULL) failed! (err %d).", err);
17803fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad                return err;
17813fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad            }
17823fb3917ae19f07ddfb2176a9da3c7cfa514522a5Rachad
17835a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            // Always try to enable dynamic output buffers on native surface
17845a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            err = mOMX->storeMetaDataInBuffers(
1785054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
17865a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (err != OK) {
17875a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1788fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1789e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
17905a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // if adaptive playback has been requested, try JB fallback
17915a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
17925a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // LARGE MEMORY REQUIREMENT
17935a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
17945a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // we will not do adaptive playback on software accessed
17955a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // surfaces as they never had to respond to changes in the
17965a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // crop window, and we don't trust that they will be able to.
17975a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int usageBits = 0;
17985a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                bool canDoAdaptivePlayback;
17995a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18005a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (nativeWindow->query(
18015a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        nativeWindow.get(),
18025a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        NATIVE_WINDOW_CONSUMER_USAGE_BITS,
18035a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        &usageBits) != OK) {
18045a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback = false;
18055a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                } else {
18065a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    canDoAdaptivePlayback =
18075a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        (usageBits &
18085a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                (GRALLOC_USAGE_SW_READ_MASK |
18095a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                                 GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
18105a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                }
18115a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18125a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                int32_t maxWidth = 0, maxHeight = 0;
18135a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                if (canDoAdaptivePlayback &&
18145a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-width", &maxWidth) &&
18155a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        msg->findInt32("max-height", &maxHeight)) {
18165a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
18175a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), maxWidth, maxHeight);
18185a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18195a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    err = mOMX->prepareForAdaptivePlayback(
18205a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mNode, kPortIndexOutput, OMX_TRUE, maxWidth,
18215a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            maxHeight);
18225a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    ALOGW_IF(err != OK,
18235a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            "[%s] prepareForAdaptivePlayback failed w/ err %d",
18245a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                            mComponentName.c_str(), err);
18255a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
18265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    if (err == OK) {
18275a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-width", maxWidth);
18285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("max-height", maxHeight);
18295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        inputFormat->setInt32("adaptive-playback", true);
18305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    }
1831e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
18325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                // allow failure
18335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                err = OK;
18345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            } else {
18355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                ALOGV("[%s] storeMetaDataInBuffers succeeded",
18365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                        mComponentName.c_str());
1837054219874873b41f1c815552987c10465c34ba2bLajos Molnar                CHECK(storingMetadataInDecodedBuffers());
1838011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
1839011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        "legacy-adaptive", !msg->contains("no-experiments"));
1840011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar
18415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                inputFormat->setInt32("adaptive-playback", true);
1842fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
18430167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
18445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            int32_t push;
18455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
18465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                    && push != 0) {
18475a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
18485a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            }
18490167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1850e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang
1851e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        int32_t rotationDegrees;
1852e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
1853e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = rotationDegrees;
1854e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        } else {
1855e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang            mRotationDegrees = 0;
1856e9e63bcf6c36351f1129b0bdc5e93f17f0f9f0b4Chong Zhang        }
1857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1859308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
18603a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // determine need for software renderer
18613a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        bool usingSwRenderer = false;
18623a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
18633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            usingSwRenderer = true;
18643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            haveNativeWindow = false;
18653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
18663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
18700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setupVideoDecoder(mime, msg, haveNativeWindow);
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (err != OK) {
18743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            return err;
18753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
18763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
18781de1e25cba872bd4c077c2e394f8ca9c70b65856Lajos Molnar            mNativeWindow = static_cast<Surface *>(obj.get());
18793a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
18803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // initialize native window now to get actual output format
18823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // TODO: this is needed for some encoders even though they don't use native window
1883777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = initNativeWindow();
1884777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err != OK) {
1885777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return err;
1886777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
18873a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
18883a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        // fallback for devices that do not handle flex-YUV for native buffers
18893a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (haveNativeWindow) {
18903a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
18913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            if (msg->findInt32("color-format", &requestedColorFormat) &&
18923a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    requestedColorFormat == OMX_COLOR_FormatYUV420Flexible) {
1893777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                status_t err = getPortFormat(kPortIndexOutput, outputFormat);
1894777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (err != OK) {
1895777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return err;
1896777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
18973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                int32_t colorFormat = OMX_COLOR_FormatUnused;
18983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                OMX_U32 flexibleEquivalent = OMX_COLOR_FormatUnused;
1899777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!outputFormat->findInt32("color-format", &colorFormat)) {
1900777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("ouptut port did not have a color format (wrong domain?)");
1901777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_VALUE;
1902777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
19033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                ALOGD("[%s] Requested output format %#x and got %#x.",
19043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mComponentName.c_str(), requestedColorFormat, colorFormat);
19053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                if (!isFlexibleColorFormat(
19063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                                mOMX, mNode, colorFormat, haveNativeWindow, &flexibleEquivalent)
19073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        || flexibleEquivalent != (OMX_U32)requestedColorFormat) {
19083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // device did not handle flex-YUV request for native window, fall back
19093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    // to SW renderer
19103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    ALOGI("[%s] Falling back to software renderer", mComponentName.c_str());
19113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    mNativeWindow.clear();
19123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    haveNativeWindow = false;
19133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    usingSwRenderer = true;
1914054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    if (storingMetadataInDecodedBuffers()) {
1915054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        err = mOMX->storeMetaDataInBuffers(
1916054219874873b41f1c815552987c10465c34ba2bLajos Molnar                                mNode, kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
1917054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
19183a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // TODO: implement adaptive-playback support for bytebuffer mode.
19193a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // This is done by SW codecs, but most HW codecs don't support it.
19203a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        inputFormat->setInt32("adaptive-playback", false);
19213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19223a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (err == OK) {
19233a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
19243a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19253a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mFlags & kFlagIsGrallocUsageProtected) {
19263a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        // fallback is not supported for protected playback
19273a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = PERMISSION_DENIED;
19283a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    } else if (err == OK) {
19293a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        err = setupVideoDecoder(mime, msg, false);
19303a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
19313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                }
19323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            }
19333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
19343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar
19353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        if (usingSwRenderer) {
19363a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar            outputFormat->setInt32("using-sw-renderer", 1);
19373a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar        }
193842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
193942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
194042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
194142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
194242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
194342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
194442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
194542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
194642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
194742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
194842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
194942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
195042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1957aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1958b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            int32_t sbrMode;
19598045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            int32_t maxOutputChannelCount;
19602965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            int32_t pcmLimiterEnable;
19618045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            drcParams_t drc;
1962ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1963ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1964ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1965aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1966aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1967aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1968b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            if (!msg->findInt32("aac-sbr-mode", &sbrMode)) {
1969b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi                sbrMode = -1;
1970b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            }
1971ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
19728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-max-output-channel_count", &maxOutputChannelCount)) {
19738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                maxOutputChannelCount = -1;
19748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19752965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            if (!msg->findInt32("aac-pcm-limiter-enable", &pcmLimiterEnable)) {
19762965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                // value is unknown
19772965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                pcmLimiterEnable = -1;
19782965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang            }
19798045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-encoded-target-level", &drc.encodedTargetLevel)) {
19808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.encodedTargetLevel = -1;
19828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-cut-level", &drc.drcCut)) {
19848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcCut = -1;
19868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-boost-level", &drc.drcBoost)) {
19888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.drcBoost = -1;
19908045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19918045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-drc-heavy-compression", &drc.heavyCompression)) {
19928045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19938045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.heavyCompression = -1;
19948045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19958045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            if (!msg->findInt32("aac-target-ref-level", &drc.targetRefLevel)) {
19968045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                // value is unknown
19978045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                drc.targetRefLevel = -1;
19988045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi            }
19998045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
2000ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
20014471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
20022965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    isADTS != 0, sbrMode, maxOutputChannelCount, drc,
20032965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang                    pcmLimiterEnable);
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2005729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
2007729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
2009729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
2010729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
2011729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
2012729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
2013729de186450f78c099637e1fce743fe531862c52Andreas Huber
2014729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
201817c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            int32_t sampleRate;
201917c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            if (!msg->findInt32("sample-rate", &sampleRate)) {
202017c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen                sampleRate = 8000;
202117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            }
202217c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            err = setupG711Codec(encoder, sampleRate, numChannels);
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
2025ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
20262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
20272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
20282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
20292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
20302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
20312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
20322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
2033516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
2034cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                            "complexity", &compressionLevel) &&
2035cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    !msg->findInt32(
2036516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
2037cd39746f8d83bb3f12e8f613e77c3c3b5f77c077Lajos Molnar                    compressionLevel = 5; // default FLAC compression level
20382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
2039516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2040516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
2041516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
20422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
20432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
2044516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
2045516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
2046516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
20472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
20482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
20492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
2050516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
2051516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
20522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
2053ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
2054ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
2055ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
2056ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
2057ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
2058ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
2059ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
2060ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
2061ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
206297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
206397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
206497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
206597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
206697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
206797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
206897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
206997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
207097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
20718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
20728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t numChannels;
20738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        int32_t sampleRate;
20748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        if (!msg->findInt32("channel-count", &numChannels)
20758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                || !msg->findInt32("sample-rate", &sampleRate)) {
20768a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = INVALID_OPERATION;
20778a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        } else {
20788a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            err = setupEAC3Codec(encoder, numChannels, sampleRate);
20798a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        }
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2081729de186450f78c099637e1fce743fe531862c52Andreas Huber
20824471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
20834471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
20844471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
20854471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
20868b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
20878b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
20888b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
20899806555d3930be43e11106281dee354820ac1c88Andreas Huber
20908b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
20918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
20928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
20938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
20949806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
20959806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
20969806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
20979806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
20989806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
20999806555d3930be43e11106281dee354820ac1c88Andreas Huber
2100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
2101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
2103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
2105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21078b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    int32_t priority;
21088b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (msg->findInt32("priority", &priority)) {
21098b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        err = setPriority(priority);
21108b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21118b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2112ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    int32_t rateInt = -1;
2113ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    float rateFloat = -1;
2114ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (!msg->findFloat("operating-rate", &rateFloat)) {
2115ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        msg->findInt32("operating-rate", &rateInt);
2116ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rateFloat = (float)rateInt;  // 16MHz (FLINTMAX) is OK for upper bound.
2117ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2118ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat > 0) {
2119ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        err = setOperatingRate(rateFloat, video);
2120ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2121ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
21224e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mBaseOutputFormat = outputFormat;
21234e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar
2124777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    err = getPortFormat(kPortIndexInput, inputFormat);
2125777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err == OK) {
2126777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        err = getPortFormat(kPortIndexOutput, outputFormat);
2127777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        if (err == OK) {
2128777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mInputFormat = inputFormat;
2129777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            mOutputFormat = outputFormat;
2130777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        }
2131777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
21358b806ea894ca098366629458bfdd1df4866afcdfRonghua Wustatus_t ACodec::setPriority(int32_t priority) {
21368b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (priority < 0) {
21378b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        return BAD_VALUE;
21388b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21398b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    OMX_PARAM_U32TYPE config;
21408b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    InitOMXParams(&config);
21418b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    config.nU32 = (OMX_U32)priority;
21428b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    status_t temp = mOMX->setConfig(
21438b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigPriority,
21448b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu            &config, sizeof(config));
21458b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    if (temp != OK) {
21468b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu        ALOGI("codec does not support config priority (err %d)", temp);
21478b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    }
21488b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu    return OK;
21498b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu}
21508b806ea894ca098366629458bfdd1df4866afcdfRonghua Wu
2151ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wustatus_t ACodec::setOperatingRate(float rateFloat, bool isVideo) {
2152ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (rateFloat < 0) {
2153ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        return BAD_VALUE;
2154ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2155ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_U32 rate;
2156ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (isVideo) {
2157ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > 65535) {
2158ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2159ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2160ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat * 65536.0f + 0.5f);
2161ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    } else {
2162ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        if (rateFloat > UINT_MAX) {
2163ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            return BAD_VALUE;
2164ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        }
2165ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        rate = (OMX_U32)(rateFloat);
2166ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2167ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    OMX_PARAM_U32TYPE config;
2168ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    InitOMXParams(&config);
2169ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    config.nU32 = rate;
2170ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    status_t err = mOMX->setConfig(
2171ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            mNode, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate,
2172ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu            &config, sizeof(config));
2173ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    if (err != OK) {
2174ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu        ALOGI("codec does not support config operating rate (err %d)", err);
2175ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    }
2176ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu    return OK;
2177ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu}
2178ed5554fb1c837f6b1008d3910018c979c57da502Ronghua Wu
2179f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
2180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
2192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
2193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
2196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
2205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2211777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.nBufferSize < size) {
2212777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("failed to set min buffer size to %zu (is still %u)", size, def.nBufferSize);
2213777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
2214777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
2215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
2246aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
22478045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        int32_t bitRate, int32_t aacProfile, bool isADTS, int32_t sbrMode,
22482965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t maxOutputChannelCount, const drcParams_t& drc,
22492965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang        int32_t pcmLimiterEnable) {
2250ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
2251ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
2252ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2253ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
2314aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
2316b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        switch (sbrMode) {
2317b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 0:
2318b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // disable sbr
2319b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2320b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2321b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2322b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 1:
2323b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable single-rate sbr
2324b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2325b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidDSBR;
2326b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2327b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case 2:
2328b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable dual-rate sbr
2329b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools &= ~OMX_AUDIO_AACToolAndroidSSBR;
2330b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2331b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2332b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        case -1:
2333b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // enable both modes -> the codec will decide which mode should be used
2334b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidSSBR;
2335b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            profile.nAACtools |= OMX_AUDIO_AACToolAndroidDSBR;
2336b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            break;
2337b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        default:
2338b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            // unsupported sbr mode
2339b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi            return BAD_VALUE;
2340b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi        }
2341b97cc6a9a3c81215e365c61b071a932073b56ff2Jean-Michel Trivi
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
2366ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2367ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
2368ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
2369ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
2370ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
23728045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE presentation;
23738045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nMaxOutputChannels = maxOutputChannelCount;
23748045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcCut = drc.drcCut;
23758045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nDrcBoost = drc.drcBoost;
23768045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nHeavyCompression = drc.heavyCompression;
23778045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nTargetReferenceLevel = drc.targetRefLevel;
23788045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
23792965f4eb7dceaf1173f0e2d93c11c28293aeead7Chong Zhang    presentation.nPCMLimiterEnable = pcmLimiterEnable;
23808045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi
23818045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    status_t res = mOMX->setParameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
23828045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    if (res == OK) {
23838045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        // optional parameters, will not cause configuration failure
23848045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacPresentation,
23858045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi                &presentation, sizeof(presentation));
23868045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    } else {
23878045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi        ALOGW("did not set AudioAndroidAacPresentation due to error %d when setting AudioAac", res);
23888045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    }
23898045853d03649f43ea2f7107e7d2dbb9b2d20855Jean-Michel Trivi    return res;
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
239397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
239497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
239597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
239697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
239797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
239897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
239997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
240097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
240197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
240297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
240397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
240497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
240597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
240697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
240797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
240897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
240997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
241097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
241197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
241297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
241397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
241497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
241597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
241697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
241797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
241897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
241997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
242097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
242197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
242297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
242397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
242497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
242597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
242697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
242797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
242897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
242997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
24308a4728966dc9c78e21c3c93a927707e93c05e5e0Rachadstatus_t ACodec::setupEAC3Codec(
24318a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        bool encoder, int32_t numChannels, int32_t sampleRate) {
24328a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    status_t err = setupRawAudioFormat(
24338a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
24348a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
24358a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
24368a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
24378a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
24388a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
24398a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (encoder) {
24408a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        ALOGW("EAC3 encoding is not supported.");
24418a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return INVALID_OPERATION;
24428a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
24438a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
24448a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE def;
24458a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    InitOMXParams(&def);
24468a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nPortIndex = kPortIndexInput;
24478a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
24488a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    err = mOMX->getParameter(
24498a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
24508a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
24518a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
24528a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
24538a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
24548a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    if (err != OK) {
24558a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad        return err;
24568a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    }
24578a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
24588a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nChannels = numChannels;
24598a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    def.nSampleRate = sampleRate;
24608a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
24618a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad    return mOMX->setParameter(
24628a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            mNode,
24638a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
24648a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            &def,
24658a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad            sizeof(def));
24668a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad}
24678a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
2514729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
2515729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
2517729de186450f78c099637e1fce743fe531862c52Andreas Huber
2518729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
2519729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2520729de186450f78c099637e1fce743fe531862c52Andreas Huber
2521729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2522729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2523729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2524729de186450f78c099637e1fce743fe531862c52Andreas Huber
2525729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
2530729de186450f78c099637e1fce743fe531862c52Andreas Huber
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2534729de186450f78c099637e1fce743fe531862c52Andreas Huber
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
2539729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2540729de186450f78c099637e1fce743fe531862c52Andreas Huber
254117c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissenstatus_t ACodec::setupG711Codec(bool encoder, int32_t sampleRate, int32_t numChannels) {
2542777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (encoder) {
2543777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return INVALID_OPERATION;
2544777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2546729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
254717c39e708ed657b8fa66f8acce5128e51696915cMarco Nelissen            kPortIndexInput, sampleRate, numChannels);
2548729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2549729de186450f78c099637e1fce743fe531862c52Andreas Huber
25502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
25512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
25522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
25532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
25542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
25552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
25562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
25572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
25582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
25592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
25602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
25612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
25622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
25632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
25642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
25652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
25662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
25672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
25682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
25692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
25702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
25712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
25722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
25732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
25742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
25752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
25762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
25772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
2578729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
2579729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
2580729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2581729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
2582729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
2583729de186450f78c099637e1fce743fe531862c52Andreas Huber
2584729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
2585729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2586729de186450f78c099637e1fce743fe531862c52Andreas Huber
2587729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2588729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2589729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2590729de186450f78c099637e1fce743fe531862c52Andreas Huber
2591729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2592729de186450f78c099637e1fce743fe531862c52Andreas Huber
2593729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
2594729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2595729de186450f78c099637e1fce743fe531862c52Andreas Huber
2596729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2597729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2598729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2599729de186450f78c099637e1fce743fe531862c52Andreas Huber
2600729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
2601729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
2602729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
2603729de186450f78c099637e1fce743fe531862c52Andreas Huber
2604729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
2605729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2606729de186450f78c099637e1fce743fe531862c52Andreas Huber
2607729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
2608729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
2609729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2610729de186450f78c099637e1fce743fe531862c52Andreas Huber
2611729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
2612729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
2613729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
2614729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
2615729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
2616729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
2617729de186450f78c099637e1fce743fe531862c52Andreas Huber
2618c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
2619c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
2620729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
2621729de186450f78c099637e1fce743fe531862c52Andreas Huber
2622729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
2623729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
2624729de186450f78c099637e1fce743fe531862c52Andreas Huber}
2625729de186450f78c099637e1fce743fe531862c52Andreas Huber
26265a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachadstatus_t ACodec::configureTunneledVideoPlayback(
262797827bd7c7e64dec22c8fe0f9e734a3c432ad7eeRachad        int32_t audioHwSync, const sp<ANativeWindow> &nativeWindow) {
26285a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    native_handle_t* sidebandHandle;
26295a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
26305a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    status_t err = mOMX->configureVideoTunnelMode(
26315a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad            mNode, kPortIndexOutput, OMX_TRUE, audioHwSync, &sidebandHandle);
26325a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
26335a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("configureVideoTunnelMode failed! (err %d).", err);
26345a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
26355a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
26365a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
26375a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
26385a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    if (err != OK) {
26395a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).",
26405a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad                sidebandHandle, err);
26415a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad        return err;
26425a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    }
26435a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
26445a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad    return OK;
26455a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad}
26465a446aafff3020d607ad6fb14cc7ae76dd8f7947Rachad
2647f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
26500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat,
26510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        bool usingNativeBuffers) {
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
2662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
2663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
2664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
2666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
2667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2669229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // substitute back flexible color format to codec supported format
2670229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        OMX_U32 flexibleEquivalent;
26710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (compressionFormat == OMX_VIDEO_CodingUnused
26720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
26730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, usingNativeBuffers, &flexibleEquivalent)
26740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && colorFormat == flexibleEquivalent) {
2675229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            ALOGI("[%s] using color format %#x in place of %#x",
2676229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                    mComponentName.c_str(), format.eColorFormat, colorFormat);
2677229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            colorFormat = format.eColorFormat;
2678229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
2679229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
2680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
2681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
2682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
2684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
2685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
2686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
2687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
2691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
2712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27180d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Set optimal output format. OMX component lists output formats in the order
27190d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// of preference, but this got more complicated since the introduction of flexible
27200d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// YUV formats. We support a legacy behavior for applications that do not use
27210d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// surface output, do not specify an output format, but expect a "usable" standard
27220d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// OMX format. SW readable and standard formats must be flex-YUV.
27230d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
27240d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// Suggested preference order:
27250d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal format for texture rendering (mediaplayer behavior)
27260d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable & texture renderable format (flex-YUV support)
27270d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - optimal SW readable non-renderable format (flex-YUV bytebuffer support)
27280d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// - legacy "usable" standard formats
27290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar//
27300d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// For legacy support, we prefer a standard format, but will settle for a SW readable
27310d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar// flex-YUV format.
27320d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnarstatus_t ACodec::setSupportedOutputFormat(bool getLegacyFlexibleFormat) {
27330d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    OMX_VIDEO_PARAM_PORTFORMATTYPE format, legacyFormat;
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27370d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    InitOMXParams(&legacyFormat);
27380d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    // this field will change when we find a suitable legacy format
27390d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    legacyFormat.eColorFormat = OMX_COLOR_FormatUnused;
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27410d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    for (OMX_U32 index = 0; ; ++index) {
27420d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        format.nIndex = index;
27430d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        status_t err = mOMX->getParameter(
27440d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                mNode, OMX_IndexParamVideoPortFormat,
27450d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                &format, sizeof(format));
27460d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (err != OK) {
27470d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            // no more formats, pick legacy format if found
27480d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            if (legacyFormat.eColorFormat != OMX_COLOR_FormatUnused) {
27490d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 memcpy(&format, &legacyFormat, sizeof(format));
27500d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                 break;
27510d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            }
27520d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return err;
27530d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
27540d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eCompressionFormat != OMX_VIDEO_CodingUnused) {
27550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            return OMX_ErrorBadParameter;
27560d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
27570d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (!getLegacyFlexibleFormat) {
27580d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
27590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
27600d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // standard formats that were exposed to users before
27610d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (format.eColorFormat == OMX_COLOR_FormatYUV420Planar
27620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar
27630d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
27640d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar
27650d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) {
27660d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            break;
27670d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
27680d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        // find best legacy non-standard format
27690d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        OMX_U32 flexibleEquivalent;
27700d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        if (legacyFormat.eColorFormat == OMX_COLOR_FormatUnused
27710d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && isFlexibleColorFormat(
27720d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        mOMX, mNode, format.eColorFormat, false /* usingNativeBuffers */,
27730d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        &flexibleEquivalent)
27740d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                && flexibleEquivalent == OMX_COLOR_FormatYUV420Flexible) {
27750d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            memcpy(&legacyFormat, &format, sizeof(format));
27760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        }
27770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    }
2778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
2779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
2780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
2781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
2784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
2785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
2786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
2787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
27882472b1c0d63454e5d90a982bd6c555de6c3127bdRachad    { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
2789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
2790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
2791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
279294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
279394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
2794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
2795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
27965778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
27975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
2798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
2802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
2803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
2808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
2810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
2813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
2814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
2815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
2816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
2817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
2818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
2819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
2820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2821e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
2824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
28265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
28275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
28290d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        const char *mime, const sp<AMessage> &msg, bool haveNativeWindow) {
283089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t width, height;
283189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (!msg->findInt32("width", &width)
283289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            || !msg->findInt32("height", &height)) {
283389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        return INVALID_OPERATION;
283489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
283589869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
28375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
28405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    int32_t tmp;
285189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    if (msg->findInt32("color-format", &tmp)) {
285289869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        OMX_COLOR_FORMATTYPE colorFormat =
285389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            static_cast<OMX_COLOR_FORMATTYPE>(tmp);
285489869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        err = setVideoPortFormatType(
28550d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                kPortIndexOutput, OMX_VIDEO_CodingUnused, colorFormat, haveNativeWindow);
285689869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        if (err != OK) {
285789869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar            ALOGW("[%s] does not support color format %d",
285889869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar                  mComponentName.c_str(), colorFormat);
28590d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar            err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
286089869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar        }
286189869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    } else {
28620d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar        err = setSupportedOutputFormat(!haveNativeWindow /* getLegacyFlexibleFormat */);
286389869f692c35d0ca914c7de4a1f5ff63c9920634Lajos Molnar    }
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    int32_t frameRateInt;
287078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    float frameRateFloat;
287178b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    if (!msg->findFloat("frame-rate", &frameRateFloat)) {
287278b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (!msg->findInt32("frame-rate", &frameRateInt)) {
287378b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            frameRateInt = -1;
287478b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
287578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        frameRateFloat = (float)frameRateInt;
287678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad    }
287778b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
287978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            kPortIndexInput, width, height, compressionFormat, frameRateFloat);
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
28975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
28985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
28995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
29035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
29065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
29095778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
29155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
29225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
29315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
29325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
29335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
29345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
29385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
29395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
29415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
29425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
29435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
29465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
29485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
29495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
29505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
29535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
29555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
29575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
29585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
29595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
29605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
29615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
29632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
29645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
2968a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // this is redundant as it was already set up in setVideoPortFormatType
2969a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    // FIXME for now skip this only for flexible YUV formats
2970a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
2971a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar        video_def->eColorFormat = colorFormat;
2972a32d5435d9585794b72dd12546054f13adb845f2Lajos Molnar    }
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
29755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
29765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
29855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
29875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
29885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
29915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
29925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
29945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
29955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
29975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
30045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
30135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
30145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
30175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
30185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
30215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
30235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
30245778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
30315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
30325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
30335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
30365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
30375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
30395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
30415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3042c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        case OMX_VIDEO_CodingHEVC:
3043c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            err = setupHEVCEncoderParameters(msg);
3044c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            break;
3045c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
304689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
304789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
304889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
304989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
305089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
30535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3055d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    if (err == OK) {
3056d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu        ALOGI("setupVideoEncoder succeeded");
3057d36a023778256f0550e9a09e9993c066e8a3c7d7Ronghua Wu    }
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
30630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
30640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
30650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
30660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
30680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
30700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
30710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
30720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
30730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
30740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
30750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
30760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
30770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
30790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
30800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
30810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
30820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
30830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
30840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
30850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
30870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
30880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
30890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
30900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
30910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
30920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
30940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
30950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
30960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
30970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
30980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
30995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
31005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
31015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
31025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
31045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
310996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
311096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
311196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
311296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
311396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
311496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
311596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
311696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
311796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
31225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
312596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
312696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
31485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
31495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
31505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
31525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
31535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
31555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
31565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
31575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
31595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
31605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
31615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
31625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
31635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
31645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
31655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
31715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
31765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
31775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
31805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
31815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
31845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
319096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
31935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
31945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
31975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
32025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
320696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
320796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
32085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
32105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
32115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
32125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
32135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
32155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
32185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
32195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
32205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
32295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
32305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
32325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
32335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
32345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
32365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
32385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
32395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
32405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
32415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
32425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
32475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
32485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
32515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
32525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
32555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
32565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
32575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
32585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
32605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
32615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
326696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
32675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
32695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
32705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
32735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3275a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar// static
3276a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnarint /* OMX_VIDEO_AVCLEVELTYPE */ ACodec::getAVCLevelFor(
3277a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        int width, int height, int rate, int bitrate,
3278a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        OMX_VIDEO_AVCPROFILETYPE profile) {
3279a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert bitrate to main/baseline profile kbps equivalent
3280a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    switch (profile) {
3281a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh10:
3282a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 3000); break;
3283a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        case OMX_VIDEO_AVCProfileHigh:
3284a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1250); break;
3285a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        default:
3286a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            bitrate = divUp(bitrate, 1000); break;
3287a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3288a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3289a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    // convert size and rate to MBs
3290a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    width = divUp(width, 16);
3291a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    height = divUp(height, 16);
3292a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int mbs = width * height;
3293a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    rate *= mbs;
3294a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    int maxDimension = max(width, height);
3295a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3296a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    static const int limits[][5] = {
3297a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        /*   MBps     MB   dim  bitrate        level */
3298a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,     64, OMX_VIDEO_AVCLevel1  },
3299a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    1485,    99,  28,    128, OMX_VIDEO_AVCLevel1b },
3300a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    3000,   396,  56,    192, OMX_VIDEO_AVCLevel11 },
3301a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {    6000,   396,  56,    384, OMX_VIDEO_AVCLevel12 },
3302a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,    768, OMX_VIDEO_AVCLevel13 },
3303a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   11880,   396,  56,   2000, OMX_VIDEO_AVCLevel2  },
3304a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   19800,   792,  79,   4000, OMX_VIDEO_AVCLevel21 },
3305a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   20250,  1620, 113,   4000, OMX_VIDEO_AVCLevel22 },
3306a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {   40500,  1620, 113,  10000, OMX_VIDEO_AVCLevel3  },
3307a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  108000,  3600, 169,  14000, OMX_VIDEO_AVCLevel31 },
3308a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  216000,  5120, 202,  20000, OMX_VIDEO_AVCLevel32 },
3309a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  20000, OMX_VIDEO_AVCLevel4  },
3310a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  245760,  8192, 256,  50000, OMX_VIDEO_AVCLevel41 },
3311a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  522240,  8704, 263,  50000, OMX_VIDEO_AVCLevel42 },
3312a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  589824, 22080, 420, 135000, OMX_VIDEO_AVCLevel5  },
3313a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        {  983040, 36864, 543, 240000, OMX_VIDEO_AVCLevel51 },
3314a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        { 2073600, 36864, 543, 240000, OMX_VIDEO_AVCLevel52 },
3315a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    };
3316a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
3317a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    for (size_t i = 0; i < ARRAY_SIZE(limits); i++) {
3318a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        const int (&limit)[5] = limits[i];
3319a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        if (rate <= limit[0] && mbs <= limit[1] && maxDimension <= limit[2]
3320a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar                && bitrate <= limit[3]) {
3321a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar            return limit[4];
3322a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar        }
3323a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    }
3324a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar    return 0;
3325a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar}
3326a147b4f91143d9f2fb608e22f9fca14bbd029573Lajos Molnar
33275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
33285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
33295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
33305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
333496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
333596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
33365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
33375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
33385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
33395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
33405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
33415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
33435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
33460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
33470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
33480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
33490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
33500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
33510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
33520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
33530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
33540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
33550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
33565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
33575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
33585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
33595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
33625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
33645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
33655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
33685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
33695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
33715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
33725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
33735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
33745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
33755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
33785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
33805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
33815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
33845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
33855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
33887c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
33897c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
33907c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
33915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
33925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
33955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
33985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
33995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
34005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
34015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
34035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
34045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
34055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
34065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
34085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
34095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
34105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
34115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
34145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
34155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
34185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
34195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
34205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
34215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
34225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
34235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
34245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
34265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
34275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
34295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
34305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
34315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
343296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3435c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachadstatus_t ACodec::setupHEVCEncoderParameters(const sp<AMessage> &msg) {
3436c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t bitrate, iFrameInterval;
3437c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findInt32("bitrate", &bitrate)
3438c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
3439c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return INVALID_OPERATION;
3440c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3441c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3442c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
3443c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3444c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    float frameRate;
3445c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (!msg->findFloat("frame-rate", &frameRate)) {
3446c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t tmp;
3447c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("frame-rate", &tmp)) {
3448c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3449c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3450c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        frameRate = (float)tmp;
3451c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3452c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3453c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    OMX_VIDEO_PARAM_HEVCTYPE hevcType;
3454c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    InitOMXParams(&hevcType);
3455c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    hevcType.nPortIndex = kPortIndexOutput;
3456c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3457c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    status_t err = OK;
3458c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->getParameter(
3459c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3460c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3461c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3462c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3463c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3464c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    int32_t profile;
3465c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (msg->findInt32("profile", &profile)) {
3466c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        int32_t level;
3467c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (!msg->findInt32("level", &level)) {
3468c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return INVALID_OPERATION;
3469c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3470c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3471c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        err = verifySupportForProfileAndLevel(profile, level);
3472c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        if (err != OK) {
3473c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            return err;
3474c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        }
3475c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3476c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eProfile = static_cast<OMX_VIDEO_HEVCPROFILETYPE>(profile);
3477c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        hevcType.eLevel = static_cast<OMX_VIDEO_HEVCLEVELTYPE>(level);
3478c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3479c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3480c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    // TODO: Need OMX structure definition for setting iFrameInterval
3481c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3482c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    err = mOMX->setParameter(
3483c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc, &hevcType, sizeof(hevcType));
3484c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    if (err != OK) {
3485c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad        return err;
3486c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    }
3487c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
3488c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad    return configureBitrate(bitrate, bitrateMode);
3489c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad}
3490c8efda9e9cd61dfe8e486c93fa8940b77cc3ccebRachad
349189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
349289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
34934154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    int32_t iFrameInterval = 0;
34944154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    size_t tsLayers = 0;
34954154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE pattern =
34964154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        OMX_VIDEO_VPXTemporalLayerPatternNone;
34974154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    static const uint32_t kVp8LayerRateAlloction
34984154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS]
34994154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        [OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS] = {
35004154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        {100, 100, 100},  // 1 layer
35014154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 60, 100, 100},  // 2 layers {60%, 40%}
35024154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        { 40,  60, 100},  // 3 layers {40%, 20%, 40%}
35034154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    };
350489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
350589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
350689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
35074154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    msg->findInt32("i-frame-interval", &iFrameInterval);
350889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
350989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
351089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
35114154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    float frameRate;
35124154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (!msg->findFloat("frame-rate", &frameRate)) {
35134154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        int32_t tmp;
35144154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (!msg->findInt32("frame-rate", &tmp)) {
35154154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            return INVALID_OPERATION;
35164154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
35174154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        frameRate = (float)tmp;
35184154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
35194154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
35204154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    AString tsSchema;
35214154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (msg->findString("ts-schema", &tsSchema)) {
35224154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsSchema == "webrtc.vp8.1-layer") {
35234154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
35244154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 1;
35254154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.2-layer") {
35264154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
35274154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 2;
35284154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else if (tsSchema == "webrtc.vp8.3-layer") {
35294154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            pattern = OMX_VIDEO_VPXTemporalLayerPatternWebRTC;
35304154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            tsLayers = 3;
35314154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        } else {
35324154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Unsupported ts-schema [%s]", tsSchema.c_str());
35334154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
35344154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
35354154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
35364154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
35374154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    InitOMXParams(&vp8type);
35384154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    vp8type.nPortIndex = kPortIndexOutput;
35394154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    status_t err = mOMX->getParameter(
35404154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
35414154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            &vp8type, sizeof(vp8type));
35424154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
35434154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    if (err == OK) {
35444154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (iFrameInterval > 0) {
35454154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nKeyFrameInterval = setPFramesSpacing(iFrameInterval, frameRate);
35464154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
35474154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.eTemporalPattern = pattern;
35484154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        vp8type.nTemporalLayerCount = tsLayers;
35494154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (tsLayers > 0) {
35504154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            for (size_t i = 0; i < OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS; i++) {
35514154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                vp8type.nTemporalLayerBitrateRatio[i] =
35524154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                    kVp8LayerRateAlloction[tsLayers - 1][i];
35534154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            }
35544154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
35554154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (bitrateMode == OMX_Video_ControlRateConstant) {
35564154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMinQuantizer = 2;
35574154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            vp8type.nMaxQuantizer = 63;
35584154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
35594154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
35604154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        err = mOMX->setParameter(
35614154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                mNode, (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
35624154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev                &vp8type, sizeof(vp8type));
35634154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        if (err != OK) {
35644154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev            ALOGW("Extended VP8 parameters set failed: %d", err);
35654154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev        }
35664154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev    }
35674154795d5526750b7aec5f774831a9e1ba0a3f15Alex Glaznev
356889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
356989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
357089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
35715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
35725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
35735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
35765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
35795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
35805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
35815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
35855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
35905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
359796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
359896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
35995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
36005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
36025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
36045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
36055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
36065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
361196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
36255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
36295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
36405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
36415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
364578b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat,
364678b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        float frameRate) {
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3655777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3656777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3657777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3667777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDomain != OMX_PortDomainVideo) {
3668777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("expected video port, got %s(%d)", asString(def.eDomain), def.eDomain);
3669777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return FAILED_TRANSACTION;
3670777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
367878b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        if (frameRate >= 0) {
367978b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad            video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
368078b01639c08fe5e7e9c1be5e9dc5de560f1383f9Rachad        }
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
3684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
3691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
3692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3698d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
3699d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
3700d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3701d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3702d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
3703d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3704d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3705d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
3706d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
3707d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
3708d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3709d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
3710d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
3711d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
37127e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
37137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
37147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
37157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
37167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
37177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
37187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
37197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
37207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
37217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
37227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
37237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
37247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
37257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
37267e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
37277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
37287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
37297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
37307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3731e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
37327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
3733c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
3734054219874873b41f1c815552987c10465c34ba2bLajos Molnar        if (storingMetadataInDecodedBuffers() && mMetadataBuffersToSubmit > 0) {
3735054219874873b41f1c815552987c10465c34ba2bLajos Molnar            --mMetadataBuffersToSubmit;
3736c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
37377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
37387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
37397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3747609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            ALOGV("[%s] Buffer %u on port %u still has status %d",
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar// static
3777229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeDefaultColorFormat(DescribeColorFormatParams &params) {
377803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    MediaImage &image = params.sMediaImage;
377903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    memset(&image, 0, sizeof(image));
378003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
378103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
378203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 0;
378303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
378403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat;
378503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mWidth = params.nFrameWidth;
378603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mHeight = params.nFrameHeight;
378703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
378803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // only supporting YUV420
378903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    if (fmt != OMX_COLOR_FormatYUV420Planar &&
379003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedPlanar &&
379103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        fmt != OMX_COLOR_FormatYUV420SemiPlanar &&
37925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar &&
37935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        fmt != HAL_PIXEL_FORMAT_YV12) {
379403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        ALOGW("do not know color format 0x%x = %d", fmt, fmt);
3795229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
379603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
379703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3798b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // TEMPORARY FIX for some vendors that advertise sliceHeight as 0
3799b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride != 0 && params.nSliceHeight == 0) {
3800b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("using sliceHeight=%u instead of what codec advertised (=0)",
3801b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                params.nFrameHeight);
3802b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        params.nSliceHeight = params.nFrameHeight;
3803b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3804b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
3805b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    // we need stride and slice-height to be non-zero
3806b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    if (params.nStride == 0 || params.nSliceHeight == 0) {
3807b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u",
3808b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar                fmt, fmt, params.nStride, params.nSliceHeight);
3809b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar        return false;
3810b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar    }
3811b32ebac7e3afb49b41eeccf130c8a96c1dae85d1Lajos Molnar
381203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    // set-up YUV format
381303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
381403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mNumPlanes = 3;
381503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mBitDepth = 8;
381603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mOffset = 0;
381703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mColInc = 1;
381803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mRowInc = params.nStride;
381903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mHorizSubsampling = 1;
382003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    image.mPlane[image.Y].mVertSubsampling = 1;
382103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
38225a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar    switch ((int)fmt) {
38235a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case HAL_PIXEL_FORMAT_YV12:
38245a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            if (params.bUsingNativeBuffers) {
38255a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t ystride = align(params.nStride, 16);
38265a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                size_t cstride = align(params.nStride / 2, 16);
38275a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.Y].mRowInc = ystride;
38285a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
38295a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mOffset = ystride * params.nSliceHeight;
38305a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mColInc = 1;
38315a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mRowInc = cstride;
38325a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mHorizSubsampling = 2;
38335a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.V].mVertSubsampling = 2;
38345a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
38355a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mOffset = image.mPlane[image.V].mOffset
38365a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                        + (cstride * params.nSliceHeight / 2);
38375a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mColInc = 1;
38385a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mRowInc = cstride;
38395a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mHorizSubsampling = 2;
38405a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                image.mPlane[image.U].mVertSubsampling = 2;
38415a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                break;
38425a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            } else {
38435a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                // fall through as YV12 is used for YUV420Planar by some codecs
38445a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            }
38455a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
38465a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar        case OMX_COLOR_FormatYUV420Planar:
384703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedPlanar:
384803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
384903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 1;
385003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride / 2;
385103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
385203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
385303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
385403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset
385503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    + (params.nStride * params.nSliceHeight / 4);
385603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 1;
385703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride / 2;
385803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
385903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
386003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
386103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
386203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420SemiPlanar:
386303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder
386403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        case OMX_COLOR_FormatYUV420PackedSemiPlanar:
386503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            // NV12
386603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight;
386703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mColInc = 2;
386803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mRowInc = params.nStride;
386903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mHorizSubsampling = 2;
387003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.U].mVertSubsampling = 2;
387103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
387203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1;
387303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mColInc = 2;
387403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mRowInc = params.nStride;
387503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mHorizSubsampling = 2;
387603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            image.mPlane[image.V].mVertSubsampling = 2;
387703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            break;
387803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
387903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        default:
388003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            TRESPASS();
388103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar    }
3882229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return true;
3883229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3884229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3885229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3886229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::describeColorFormat(
3887229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        const sp<IOMX> &omx, IOMX::node_id node,
3888229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        DescribeColorFormatParams &describeParams)
3889229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar{
3890229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    OMX_INDEXTYPE describeColorFormatIndex;
3891229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (omx->getExtensionIndex(
3892229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, "OMX.google.android.index.describeColorFormat",
3893229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeColorFormatIndex) != OK ||
3894229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        omx->getParameter(
3895229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            node, describeColorFormatIndex,
3896229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            &describeParams, sizeof(describeParams)) != OK) {
3897229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return describeDefaultColorFormat(describeParams);
3898229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3899229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return describeParams.sMediaImage.mType !=
3900229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
3901229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar}
3902229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3903229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar// static
3904229d242665c612fd97431d1e7ac004823b47f181Lajos Molnarbool ACodec::isFlexibleColorFormat(
3905229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar         const sp<IOMX> &omx, IOMX::node_id node,
39060d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar         uint32_t colorFormat, bool usingNativeBuffers, OMX_U32 *flexibleEquivalent) {
3907229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    DescribeColorFormatParams describeParams;
3908229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    InitOMXParams(&describeParams);
3909229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.eColorFormat = (OMX_COLOR_FORMATTYPE)colorFormat;
3910229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    // reasonable dummy values
3911229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameWidth = 128;
3912229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nFrameHeight = 128;
3913229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nStride = 128;
3914229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    describeParams.nSliceHeight = 128;
39150d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar    describeParams.bUsingNativeBuffers = (OMX_BOOL)usingNativeBuffers;
3916229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3917229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    CHECK(flexibleEquivalent != NULL);
3918229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3919229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (!describeColorFormat(omx, node, describeParams)) {
3920229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        return false;
3921229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3922229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3923229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    const MediaImage &img = describeParams.sMediaImage;
3924229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    if (img.mType == MediaImage::MEDIA_IMAGE_TYPE_YUV) {
3925229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mNumPlanes != 3 ||
3926229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mHorizSubsampling != 1 ||
3927229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            img.mPlane[img.Y].mVertSubsampling != 1) {
3928229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            return false;
3929229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3930229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar
3931229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        // YUV 420
3932229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        if (img.mPlane[img.U].mHorizSubsampling == 2
3933229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.U].mVertSubsampling == 2
3934229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mHorizSubsampling == 2
3935229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar                && img.mPlane[img.V].mVertSubsampling == 2) {
3936229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            // possible flexible YUV420 format
3937229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            if (img.mBitDepth <= 8) {
3938229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               *flexibleEquivalent = OMX_COLOR_FormatYUV420Flexible;
3939229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar               return true;
3940229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar            }
3941229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar        }
3942229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    }
3943229d242665c612fd97431d1e7ac004823b47f181Lajos Molnar    return false;
394403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar}
394503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
3946e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
3947777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    const char *niceIndex = portIndex == kPortIndexInput ? "input" : "output";
394831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
394931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
3950e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
395131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3952777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    status_t err = mOMX->getParameter(mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
3953777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (err != OK) {
3954777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return err;
3955777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
395631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3957777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (def.eDir != (portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput)) {
3958777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("unexpected dir: %s(%d) on %s port", asString(def.eDir), def.eDir, niceIndex);
3959777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return BAD_VALUE;
3960777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
396131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
396231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
396331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
396431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
396531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
3966e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
3967e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
3968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
3969e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
3970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
3971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
3972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
3973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
3974e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
3975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
39760d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                    if (mNativeWindow == NULL) {
39770d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        DescribeColorFormatParams describeParams;
39780d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        InitOMXParams(&describeParams);
39790d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.eColorFormat = videoDef->eColorFormat;
39800d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameWidth = videoDef->nFrameWidth;
39810d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nFrameHeight = videoDef->nFrameHeight;
39820d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nStride = videoDef->nStride;
39830d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.nSliceHeight = videoDef->nSliceHeight;
39840d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        describeParams.bUsingNativeBuffers = OMX_FALSE;
39850d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar
39860d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        if (describeColorFormat(mOMX, mNode, describeParams)) {
39870d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                            notify->setBuffer(
39880d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    "image-data",
39890d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                    ABuffer::CreateAsCopy(
39900d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            &describeParams.sMediaImage,
39910d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                                            sizeof(describeParams.sMediaImage)));
39925a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
39935a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            MediaImage *img = &describeParams.sMediaImage;
39945a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                            ALOGV("[%s] MediaImage { F(%zux%zu) @%zu+%zu+%zu @%zu+%zu+%zu @%zu+%zu+%zu }",
39955a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    mComponentName.c_str(), img->mWidth, img->mHeight,
39965a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[0].mOffset, img->mPlane[0].mColInc, img->mPlane[0].mRowInc,
39975a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[1].mOffset, img->mPlane[1].mColInc, img->mPlane[1].mRowInc,
39985a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                                    img->mPlane[2].mOffset, img->mPlane[2].mColInc, img->mPlane[2].mRowInc);
39990d09182a1dde960f7acda1c28469e5deead1b996Lajos Molnar                        }
400003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                    }
400103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
400291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    if (portIndex != kPortIndexOutput) {
400391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        // TODO: also get input crop
400491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                        break;
400591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    }
400691a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar
4007e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
4008e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
400991a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                    rect.nPortIndex = portIndex;
4010e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4011e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
401291a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                mNode,
401391a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                (portIndex == kPortIndexOutput ?
401491a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonOutputCrop :
401591a3cc00db31a713a25848f345bd624ac2ad8dc5Lajos Molnar                                        OMX_IndexConfigCommonInputCrop),
4016e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
4017e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
4018e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
4019e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
4020e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
4021e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
402231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4023777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (rect.nLeft < 0 ||
4024777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop < 0 ||
4025777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
4026777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
4027777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Wrong cropped rect (%d, %d) - (%u, %u) vs. frame (%u, %u)",
4028777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft, rect.nTop,
4029777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                rect.nLeft + rect.nWidth, rect.nTop + rect.nHeight,
4030777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->nFrameWidth, videoDef->nFrameHeight);
4031777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4032777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4033e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4034e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
4035577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
4036577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
4037577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
4038e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
4039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
4040e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4042e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
40434730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
40444730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP8:
40454730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                case OMX_VIDEO_CodingVP9:
40464730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                {
40474730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE vp8type;
40484730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    InitOMXParams(&vp8type);
40494730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    vp8type.nPortIndex = kPortIndexOutput;
40504730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    status_t err = mOMX->getParameter(
40514730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            mNode,
40524730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            (OMX_INDEXTYPE)OMX_IndexParamVideoAndroidVp8Encoder,
40534730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            &vp8type,
40544730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            sizeof(vp8type));
40554730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
40564730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    if (err == OK) {
40574730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        AString tsSchema = "none";
40584730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        if (vp8type.eTemporalPattern
40594730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                == OMX_VIDEO_VPXTemporalLayerPatternWebRTC) {
40604730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            switch (vp8type.nTemporalLayerCount) {
40614730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 1:
40624730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
40634730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.1-layer";
40644730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
40654730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
40664730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 2:
40674730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
40684730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.2-layer";
40694730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
40704730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
40714730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                case 3:
40724730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
40734730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    tsSchema = "webrtc.vp8.3-layer";
40744730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
40754730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
40764730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                default:
40774730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                {
40784730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                    break;
40794730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                                }
40804730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                            }
40814730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        }
40824730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                        notify->setString("ts-schema", tsSchema);
40834730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    }
40844730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                    // Fall through to set up mime.
40854730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia                }
40864730fa07a3290cc3a904dcb16dbb92fcf46c36acWei Jia
4087e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
4088e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4089777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
4090777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        // should be CodingUnused
4091777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("Raw port video compression format is %s(%d)",
4092777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(videoDef->eCompressionFormat),
4093777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                videoDef->eCompressionFormat);
4094777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return BAD_VALUE;
4095777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4096e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
4097e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
4098e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
4099e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
4100e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
4101e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
4102e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
4103e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
410531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
4106e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
4107e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
41085a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar            ALOGV("[%s] %s format is %s", mComponentName.c_str(),
41095a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    portIndex == kPortIndexInput ? "input" : "output",
41105a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar                    notify->debugString().c_str());
41115a52a060fcbe4804bcf4f61b8a457fe0e18a9014Lajos Molnar
411231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
411331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
411431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
411531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
411631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
411731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
411831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
411997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
4120e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
4121e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4122e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
4123e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4124e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4125e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4126777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4127777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4128777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4129777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4130777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
413114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
4132777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (params.nChannels <= 0
4133777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || (params.nChannels != 1 && !params.bInterleaved)
4134777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.nBitPerSample != 16u
4135777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.eNumData != OMX_NumericalDataSigned
4136777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            || params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
4137777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
4138777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nChannels,
4139777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.bInterleaved ? " interleaved" : "",
4140777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                params.nBitPerSample,
4141777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.eNumData), params.eNumData,
4142777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                asString(params.ePCMMode), params.ePCMMode);
4143777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return FAILED_TRANSACTION;
4144777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4145e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4146e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
4147e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4148e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
4149e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4150e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
4151e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
41528b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
4153e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
41548b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
41559806555d3930be43e11106281dee354820ac1c88Andreas Huber
4156e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
4157e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4158e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
4159e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4160e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4161e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4162777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4163777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAac, &params, sizeof(params));
4164777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4165777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4166777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4167e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4168e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
4169e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4170e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4171e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4172e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4173e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4174e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
4175e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4176e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
4177e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
41799806555d3930be43e11106281dee354820ac1c88Andreas Huber
4180777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4181777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioAmr, &params, sizeof(params));
4182777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4183777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4184777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4185e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4186e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
4187e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
41880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
4189e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
4190e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
41910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
4192e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
4193e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
4194e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4195e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4196e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4197e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
4198e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
4199e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
4200e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
4201e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4202e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4203777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4204777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioFlac, &params, sizeof(params));
4205777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4206777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4207777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4208e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4209e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
4210e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
4211e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
4212e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
4213e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
4214e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
4215e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
4216e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4217e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
4218e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4219e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4220e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4221777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4222777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioMp3, &params, sizeof(params));
4223777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4224777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4225777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4226e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4227e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
4228e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4229e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4230e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4231e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4232e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4233e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
4234e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
4235e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
4236e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
4237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
4238e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4239777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4240777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, OMX_IndexParamAudioVorbis, &params, sizeof(params));
4241777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4242777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4243777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
4244e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4245e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
4246e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
4247e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
4248e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
4249e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
4250e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
425197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
425297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
425397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
425497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
4255e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
425697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
4257777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4258777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
4259777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4260777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4261777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4262777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
426397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
426497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
426597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
426697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
426797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
426897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
4269e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
42708a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                case OMX_AUDIO_CodingAndroidEAC3:
42718a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                {
42728a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    OMX_AUDIO_PARAM_ANDROID_EAC3TYPE params;
42738a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    InitOMXParams(&params);
42748a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    params.nPortIndex = portIndex;
42758a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
4276777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4277777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3,
4278777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4279777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4280777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4281777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
42828a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
42838a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_EAC3);
42848a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("channel-count", params.nChannels);
42858a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    notify->setInt32("sample-rate", params.nSampleRate);
42868a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                    break;
42878a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad                }
42888a4728966dc9c78e21c3c93a927707e93c05e5e0Rachad
42898c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                case OMX_AUDIO_CodingAndroidOPUS:
42908c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                {
42918c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    OMX_AUDIO_PARAM_ANDROID_OPUSTYPE params;
42928c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    InitOMXParams(&params);
42938c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    params.nPortIndex = portIndex;
42948c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
4295777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4296777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidOpus,
4297777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            &params, sizeof(params));
4298777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4299777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4300777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
43018c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
43028c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_OPUS);
43038c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("channel-count", params.nChannels);
43048c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    notify->setInt32("sample-rate", params.nSampleRate);
43058c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                    break;
43068c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian                }
43078c6693b73cb4aed9d1dcb8d5d0828a77b7471a55Vignesh Venkatasubramanian
430810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                case OMX_AUDIO_CodingG711:
430910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                {
431010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    OMX_AUDIO_PARAM_PCMMODETYPE params;
431110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    InitOMXParams(&params);
431210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    params.nPortIndex = portIndex;
431310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4314777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4315777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mNode, (OMX_INDEXTYPE)OMX_IndexParamAudioPcm, &params, sizeof(params));
4316777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4317777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4318777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
431910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
432010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    const char *mime = NULL;
432110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    if (params.ePCMMode == OMX_AUDIO_PCMModeMULaw) {
432210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_MLAW;
432310d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else if (params.ePCMMode == OMX_AUDIO_PCMModeALaw) {
432410d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_G711_ALAW;
432510d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    } else { // params.ePCMMode == OMX_AUDIO_PCMModeLinear
432610d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                        mime = MEDIA_MIMETYPE_AUDIO_RAW;
432710d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    }
432810d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setString("mime", mime);
432910d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("channel-count", params.nChannels);
433010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    notify->setInt32("sample-rate", params.nSamplingRate);
433110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                    break;
433210d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
433341d3f579d2c166984958263533284209b90c87d5Marco Nelissen
433441d3f579d2c166984958263533284209b90c87d5Marco Nelissen                case OMX_AUDIO_CodingGSMFR:
433541d3f579d2c166984958263533284209b90c87d5Marco Nelissen                {
43360806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    OMX_AUDIO_PARAM_PCMMODETYPE params;
433741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    InitOMXParams(&params);
433841d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    params.nPortIndex = portIndex;
433941d3f579d2c166984958263533284209b90c87d5Marco Nelissen
4340777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    err = mOMX->getParameter(
4341777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                                mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
4342777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    if (err != OK) {
4343777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                        return err;
4344777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    }
434541d3f579d2c166984958263533284209b90c87d5Marco Nelissen
434641d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MSGSM);
434741d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    notify->setInt32("channel-count", params.nChannels);
43480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    notify->setInt32("sample-rate", params.nSamplingRate);
434941d3f579d2c166984958263533284209b90c87d5Marco Nelissen                    break;
435010d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang                }
435110d023beb0544591d0f5ff556f7f67356f0d9189Chong Zhang
4352e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
4353777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGE("Unsupported audio coding: %s(%d)\n",
4354777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            asString(audioDef->eEncoding), audioDef->eEncoding);
4355777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return BAD_TYPE;
4356e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
435731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
435831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
435931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
436031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
4361777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unsupported domain: %s(%d)", asString(def.eDomain), def.eDomain);
4362777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return BAD_TYPE;
436331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
436431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
4365e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
4366e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
4367e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4368e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
43694e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    sp<AMessage> notify = mBaseOutputFormat->dup();
4370e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
4371e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4372777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (getPortFormat(kPortIndexOutput, notify) != OK) {
4373777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("[%s] Failed to get port format to send format change", mComponentName.c_str());
4374777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return;
4375777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
4376e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4377e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
4378e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
4379e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
4380e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
4381e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
4382e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
4383e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
4384e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
4385e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
4386e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
4387e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
4388e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
4389e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
4390e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
4391e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
4392e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
4393e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
4394e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
4395ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
4396e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
4397e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
4398e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
4399e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
4400e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
4401e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
4402e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
440331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
440431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
440531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
440631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
440731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44085778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
4409cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
4410d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatError);
4411251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    ALOGE("signalError(omxError %#x, internalError %d)", error, internalError);
4412251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
4413251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (internalError == UNKNOWN_ERROR) { // find better error code
4414251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const status_t omxStatus = statusFromOMXError(error);
4415251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        if (omxStatus != 0) {
4416251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            internalError = omxStatus;
4417251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        } else {
4418251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            ALOGW("Invalid OMX error %#x", error);
4419251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        }
4420251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
44215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
4422251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    notify->setInt32("actionCode", ACTION_CODE_FATAL); // could translate from OMX error.
4423cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
4424cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
4425cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4428eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
4429eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4430eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4431496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
4432496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
4433496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
4434496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
4435496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4436496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
4437496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
4438496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4439496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
4440496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
4441496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4442496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
4443496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
4444496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
4445496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
4446496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
4447496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
4448496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4449eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
4450eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
4451eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
4452eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
4453eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4454eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4455eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
4456eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
4457eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4458eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4459eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
4460eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
4461eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4462eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4463eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
4464eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
4465eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
4466eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4467eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
4468eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4469f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4474ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
4475ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
449326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        case ACodec::kWhatOMXMessageList:
449426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        {
449526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessageList(msg) : true;
449626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        }
449726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
450026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar            return checkOMXMessage(msg) ? onOMXMessage(msg) : true;
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case ACodec::kWhatSetSurface:
45041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
45051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
45061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
45071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
45081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<RefBase> obj;
45091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->findObject("surface", &obj));
45101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4511011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar            status_t err =
4512011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                ADebug::isExperimentEnabled("legacy-setsurface") ? BAD_VALUE :
4513011778fd4cb9606b68bfea1ed483d73c04fc6dcdLajos Molnar                        mCodec->handleSetSurface(static_cast<Surface *>(obj.get()));
45141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
45151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AMessage> response = new AMessage;
45161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->setInt32("err", err);
45171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            response->postReply(replyID);
45181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
45191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
45201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
45217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
45228f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
45237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
45247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
4525251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This may result in an app illegal state exception.
45267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
45277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
45287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
45297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
45307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4531ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
4532ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
4533251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            // This will result in kFlagSawMediaServerDie handling in MediaCodec.
4534ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
4535ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
4536ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
4537ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
4538ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
453930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
454030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
454130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGI("[%s] forcing the release of codec",
454230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                    mCodec->mComponentName.c_str());
454330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
454430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            ALOGE_IF("[%s] failed to release codec instance: err=%d",
454530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar                       mCodec->mComponentName.c_str(), err);
454630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            sp<AMessage> notify = mCodec->mNotify->dup();
454730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
454830358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            notify->post();
454930358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
455030358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
455130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::checkOMXMessage(const sp<AMessage> &msg) {
45605e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
45615e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
4562ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (mCodec->mNode == 0) {
45635e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
45645e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
456526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        return false;
45665e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
45675e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
4569609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("node", (int32_t*)&nodeID));
4570777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (nodeID != mCodec->mNode) {
4571777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGE("Unexpected message for nodeID: %u, should have been %u", nodeID, mCodec->mNode);
4572777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        return false;
4573777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
457426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
457526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
457626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
457726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessageList(const sp<AMessage> &msg) {
457826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<RefBase> obj;
457926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findObject("messages", &obj));
458026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    sp<MessageList> msgList = static_cast<MessageList *>(obj.get());
458126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
458290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    bool receivedRenderedEvents = false;
458326a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    for (std::list<sp<AMessage>>::const_iterator it = msgList->getList().cbegin();
458426a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar          it != msgList->getList().cend(); ++it) {
458526a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar        onOMXMessage(*it);
458690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int32_t type;
458790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        CHECK((*it)->findInt32("type", &type));
458890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (type == omx_message::FRAME_RENDERED) {
458990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            receivedRenderedEvents = true;
459090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
459190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
459290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
459390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (receivedRenderedEvents) {
459490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // NOTE: all buffers are rendered in this case
459590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames();
459626a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    }
459726a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    return true;
459826a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar}
459926a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar
460026a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnarbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
460126a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    int32_t type;
460226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    CHECK(msg->findInt32("type", &type));
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46120af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
46130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
46140af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
46150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
46160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
46170af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
46180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
46190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
46200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
46210af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
46220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
463215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t fenceFd;
463315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
4634609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
463515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
463715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            return onOMXEmptyBufferDone(bufferID, fenceFd);
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
4643609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
464515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            int32_t rangeOffset, rangeLength, flags, fenceFd;
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
465215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            CHECK(msg->findInt32("fence_fd", &fenceFd));
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
465815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
465915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    fenceFd);
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
466290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case omx_message::FRAME_RENDERED:
466390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
466490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            int64_t mediaTimeUs, systemNano;
466590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
466690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("media_time_us", &mediaTimeUs));
466790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            CHECK(msg->findInt64("system_nano", &systemNano));
466890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
466990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            return onOMXFrameRendered(
467090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, systemNano);
467190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
467290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4674777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Unexpected message type: %d", type);
4675777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
467990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::BaseState::onOMXFrameRendered(
468090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs __unused, nsecs_t systemNano __unused) {
468190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    // ignore outside of Executing and PortSettingsChanged states
468290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
468390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
468490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
4688ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        ALOGV("[%s] EVENT(%d, 0x%08x, 0x%08x)",
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4694ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGE("[%s] ERROR(0x%08x)", mCodec->mComponentName.c_str(), data1);
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4696251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    // verify OMX component sends back an error we expect.
4697251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    OMX_ERRORTYPE omxError = (OMX_ERRORTYPE)data1;
4698251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (!isOMXError(omxError)) {
4699251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        ALOGW("Invalid OMX error %#x", omxError);
4700251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        omxError = OMX_ErrorUndefined;
4701251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
4702251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mCodec->signalError(omxError);
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
470715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnarbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID, int fenceFd) {
4708ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] onOMXEmptyBufferDone %u",
4709349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
4710349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
47110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
47120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
47130806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
47140806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in EBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
47150806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
471615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
471715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
471815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
47190806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return false;
47200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
472315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // input buffers cannot take fences, so wait for any fence now
472415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    (void)mCodec->waitForFence(fenceFd, "onOMXEmptyBufferDone");
472515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    fenceFd = -1;
472615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
472715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // still save fence for completeness
472815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setWriteFence(fenceFd, "onOMXEmptyBufferDone");
472915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
473096e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // We're in "store-metadata-in-buffers" mode, the underlying
473196e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // OMX component had access to data that's implicitly refcounted
473296e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // by this "MediaBuffer" object. Now that the OMX component has
473396e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // told us that it's done with the input buffer, we can decrement
473496e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    // the mediaBuffer's reference count.
473596e92b58b7e9647b4c7c2f54b62a1b357ab06b66Wei Jia    info->mData->setMediaBufferBase(NULL);
4736d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4747777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4749777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("SHOULD NOT REACH HERE: cannot free empty output buffers");
4750777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
4764d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
4765609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    notify->setInt32("buffer-id", info->mBufferID);
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
47682d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47701d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec);
4771609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    reply->setInt32("buffer-id", info->mBufferID);
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
4782609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
47832d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
47855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
4786a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
47875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47882d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
4789a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47927fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
47937fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
47947fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
47957fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
47967fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
47977fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
47987fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
47997fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
48003831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
48012d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
48055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
48065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
48075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
48085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
48095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
48110806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
48120806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_UPSTREAM) {
48130806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in IBF: %s(%d) buffer #%u", _asString(status), status, bufferID);
48140806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexInput);
48150806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
48160806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
48170806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
48245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
4825dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
4826dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
4827dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
4828dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
48355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
48475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
48485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
48495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
4851ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
4852d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
4853d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
4854d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
48560806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (buffer->size() > info->mData->capacity()) {
48570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
48580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                buffer->size(),           // this is the data received
48590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                                info->mData->capacity()); // this is out buffer size
48600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
48610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        return;
48620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4866078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
4867ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ codec specific data",
4868078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
48695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
4870ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ EOS",
48715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
4872078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
4873d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4874ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGI("[%s] calling emptyBuffer %u w/ time %lld us",
4875ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4876d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
4877ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                    ALOGV("[%s] calling emptyBuffer %u w/ time %lld us",
4878ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                         mCodec->mComponentName.c_str(), bufferID, (long long)timeUs);
4879d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4880078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
4881349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4882d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
4883d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
4884d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
4885d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
4886d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
4887d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
4888d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
4889054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (mCodec->storingMetadataInDecodedBuffers()) {
4890054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
4891054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
4892054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4893054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    ALOGV("MetadataBuffersToSubmit=%u portMode=%s",
4894054219874873b41f1c815552987c10465c34ba2bLajos Molnar                            mCodec->mMetadataBuffersToSubmit,
4895054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
4896054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
4897054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
4898054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        mCodec->submitOutputMetadataBuffer();
4899054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
4900054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
490115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
49020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
49030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode,
49040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    bufferID,
49050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    0,
49060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    buffer->size(),
49070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    flags,
490815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    timeUs,
490915ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd);
491015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
49110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
49120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
49130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
49140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
49170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!eos && err == OK) {
49185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
49195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
49200806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalled EOS (%d) on the input port",
49210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                         mCodec->mComponentName.c_str(), err);
49225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
49245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
49255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
49270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK && err != ERROR_END_OF_STREAM) {
49280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGV("[%s] Signalling EOS on the input port due to error %d",
4929dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
4930dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
49313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
4932dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
4933dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4935ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] calling emptyBuffer %u signalling EOS",
4936349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
4937349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
493815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->checkReadFence("onInputBufferFilled");
49390806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err2 = mCodec->mOMX->emptyBuffer(
49400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->mNode,
49410806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        bufferID,
49420806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
49430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        0,
49440806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        OMX_BUFFERFLAG_EOS,
494515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        0,
494615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                        info->mFenceFd);
494715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
49480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err2 != OK) {
49490806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
49500806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return;
49510806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
4955dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4959625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
4960777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
4961777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            break;
4962777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
4963625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
4964777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("invalid port mode: %d", mode);
4965625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4969f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
4970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
4971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
4980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
4981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
4982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
4983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
4985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
4987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
4988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
4992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
4993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
4996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4998f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
4999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
5000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
5001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
500215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int64_t timeUs,
500315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        int fenceFd) {
5004609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    ALOGV("[%s] onOMXFillBufferDone %u time %" PRId64 " us, flags = 0x%08x",
50055778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
5006349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
5007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
50080806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err= OK;
5009d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5010d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
5011d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
5012d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
5013d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
5014d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
5015d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5016d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
5017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
5018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
5019d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5020d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
5021d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
5022d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
5023d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
5024d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
5025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
5026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
50270806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
50280806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_COMPONENT) {
50290806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in FBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
50300806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
50310806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
503215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        if (fenceFd >= 0) {
503315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            ::close(fenceFd);
503415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        }
50350806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return true;
50360806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5038054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
5039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
5040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
504190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (info->mRenderInfo != NULL) {
504290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // The fence for an emptied buffer must have signaled, but there still could be queued
504390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // or out-of-order dequeued buffers in the render queue prior to this buffer. Drop these,
504490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // as we will soon requeue this buffer to the surface. While in theory we could still keep
504590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // track of buffers that are requeued to the surface, it is better to add support to the
504690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // buffer-queue to notify us of released buffers and their fences (in the future).
504790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->notifyOfRenderedFrames(true /* dropIncomplete */);
504890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
504990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
505015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    // byte buffers cannot take fences, so wait for any fence now
505115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    if (mCodec->mNativeWindow == NULL) {
505215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        (void)mCodec->waitForFence(fenceFd, "onOMXFillBufferDone");
505315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        fenceFd = -1;
505415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    }
505515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar    info->setReadFence(fenceFd, "onOMXFillBufferDone");
505615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar
5057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5065a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar            if (rangeLength == 0 && (!(flags & OMX_BUFFERFLAG_EOS)
5066a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar                    || mCodec->mPortEOS[kPortIndexOutput])) {
5067609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                ALOGV("[%s] calling fillBuffer %u",
50685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
5069349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
507015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
507115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                info->mFenceFd = -1;
50720806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
50730806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
50740806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return true;
50750806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
5076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
50775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
50785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
50795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
508031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
5081577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
50821d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec);
5083577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
50844bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
5085577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
50865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
5087054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->usingMetadataOnEncoderOutput()) {
5088054219874873b41f1c815552987c10465c34ba2bLajos Molnar                native_handle_t *handle = NULL;
5089054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
5090054219874873b41f1c815552987c10465c34ba2bLajos Molnar                VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
5091054219874873b41f1c815552987c10465c34ba2bLajos Molnar                if (info->mData->size() >= sizeof(grallocMeta)
5092054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
50939847fcefb183e1cb09eb48e17a09577392b0e8f4Lajos Molnar                    handle = (native_handle_t *)grallocMeta.pHandle;
5094054219874873b41f1c815552987c10465c34ba2bLajos Molnar                } else if (info->mData->size() >= sizeof(nativeMeta)
5095054219874873b41f1c815552987c10465c34ba2bLajos Molnar                        && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
5096054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    handle = (native_handle_t *)nativeMeta.pBuffer->handle;
5097054219874873b41f1c815552987c10465c34ba2bLajos Molnar                }
5098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
5099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
5100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
5101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
5102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
5103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
5104496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
510521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
5106496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
5107496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
5108496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
51095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
511021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
5111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51128b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
51138b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
51148b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
51155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
5116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5118d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
5119609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            notify->setInt32("buffer-id", info->mBufferID);
51202d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
51215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
5122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5123609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            reply->setInt32("buffer-id", info->mBufferID);
5124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
5126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
51275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
51285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
5130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
51325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
51335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
5135d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar                notify->setInt32("what", CodecBase::kWhatEOS);
5136dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
5137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
5138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
5140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5144777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
51450806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffer(kPortIndexOutput, index);
51460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
51470806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
51480806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
51490806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5151777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5152777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5153777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5154777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return false;
5155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
5158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5160f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
5161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
5162609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
5163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
51640806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo *info = mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
51650806340688c937e7b78c2d89db3809274130df4eLajos Molnar    BufferInfo::Status status = BufferInfo::getSafeStatus(info);
51660806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (status != BufferInfo::OWNED_BY_DOWNSTREAM) {
51670806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGE("Wrong ownership in OBD: %s(%d) buffer #%u", _asString(status), status, bufferID);
51680806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->dumpBuffers(kPortIndexOutput);
51690806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
51700806340688c937e7b78c2d89db3809274130df4eLajos Molnar        return;
51710806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5173577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
5174777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
5175777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
5176777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
5177577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
5178577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
5179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
5180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
51816aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
518279ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
51836fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
5184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
5185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
518690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // save buffers sent to the surface so we can get render time when they return
518790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
518890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
518990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (mediaTimeUs >= 0) {
519090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            mCodec->mRenderTracker.onFrameQueued(
519190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, info->mGraphicBuffer, new Fence(::dup(info->mFenceFd)));
519290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
519390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
5194fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
5195fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (!msg->findInt64("timestampNs", &timestampNs)) {
5196fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
5197fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
5198fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
5199fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
5200fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
5201fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
520247aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
5203fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
5204fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
5205fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
5206fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
5207fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
52085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
5209fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        err = native_window_set_buffers_timestamp(mCodec->mNativeWindow.get(), timestampNs);
52100806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGW_IF(err != NO_ERROR, "failed to set buffer timestamp: %d", err);
5211fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
521215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkReadFence("onOutputBufferDrained before queueBuffer");
52130806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->mNativeWindow->queueBuffer(
521415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    mCodec->mNativeWindow.get(), info->mGraphicBuffer.get(), info->mFenceFd);
521515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
52160806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
5217cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
5218cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
5219251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5220cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
522115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // keeping read fence as write fence to avoid clobbering
522215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
5223cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
5224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
52256fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
52266fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
522715ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            // move read fence into write fence to avoid clobbering
522815ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar            info->mIsReadFence = false;
52296fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
52306fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
5231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
5232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
5235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
5237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
5238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
5240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
5243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
5244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
5246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
5251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
5253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
5254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
5255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
5256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
5258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
5259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5260c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
5261609b815a3131d22da38b2f452faa9f89daad4039Andy Hung                    ALOGV("[%s] calling fillBuffer %u",
5262c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
526315ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
526415ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    status_t err = mCodec->mOMX->fillBuffer(
526515ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                            mCodec->mNode, info->mBufferID, info->mFenceFd);
526615ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar                    info->mFenceFd = -1;
52670806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    if (err == OK) {
52680806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
52690806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    } else {
52700806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
52710806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    }
5272c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
5273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
5274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5277777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        case FREE_BUFFERS:
5278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
52790806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->freeBuffer(kPortIndexOutput, index);
52800806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
52810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
52820806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5285777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
5286777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        default:
5287777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            ALOGE("Invalid port mode: %d", mode);
5288777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            return;
5289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5294f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
5295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
5299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
5300ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5301ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
5302f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        IInterface::asBinder(mCodec->mOMX)->unlinkToDeath(mDeathNotifier);
5303ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5304ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5305ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5306ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
5307ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    mCodec->mNode = 0;
5308ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
5309ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
5310ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
5311054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
5312054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
5313ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
5314c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5316f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
5317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
5318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
5320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
5321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
5323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
5326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
53295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
53305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
53315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
53325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
53335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
53345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
5336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5337c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5338c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
534054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            ALOGW_IF(keepComponentAllocated,
534154b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar                     "cannot keep component allocated on shutdown in Uninitialized state");
5342c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5344d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
5345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5348c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
5352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5354d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
5356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
5358c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
5359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
536130358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        case ACodec::kWhatReleaseCodecInstance:
536230358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        {
536330358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            // nothing to do, as we have already signaled shutdown
536430358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            handled = true;
536530358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar            break;
536630358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar        }
536730358faf33fb9b638257b017fadb4c5f7352d903Lajos Molnar
5368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
5373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5375f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
5376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
5377c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
5378c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
5379c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
5380c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
53815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
53825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5383c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
53845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
53855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5386ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode == 0);
53875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
538948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    if (client.connect() != OK) {
539048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        mCodec->signalError(OMX_ErrorUndefined, NO_INIT);
539148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        return false;
539248a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung    }
5393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
5395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec);
5397ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5398ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
5399f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen    if (IInterface::asBinder(omx)->linkToDeath(mDeathNotifier) != OK) {
5400ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
5401ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
5402ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
5403ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
5404ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
5405e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
54065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
5408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
5410d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
54117791cf11186a22b3f84d98cfde67393bee748cb0Marco Nelissen    int32_t encoder = false;
54125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
5413e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
5414e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
5415e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
5416afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
5417e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
5418e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
5419e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
5420afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
54215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
54225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
54235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
54255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
54265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
54275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
54295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
54305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
54315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
54325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
5433e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
54345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
54351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
54361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
5437ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    IOMX::node_id node = 0;
54381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5439201d8d400eb037547f4f476a838475b13a446007Wei Jia    status_t err = NAME_NOT_FOUND;
54401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
54411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
5442e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
5443e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
5444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445da153975581fb3161a30452348a5b26ee72d9255Elliott Hughes        pid_t tid = gettid();
5446078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
5447078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
54489f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu        err = omx->allocateNode(componentName.c_str(), observer, &node);
5449078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
5450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
54521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
54537a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He        } else {
54547a727021b86c2fb2c9f60af2c999154dce1766ebZhijun He            ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
54551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
54561065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5457ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar        node = 0;
54581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
54591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5460ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (node == 0) {
54615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
54629f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
54639f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu                    encoder ? "en" : "de", mime.c_str(), err);
54645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
54659f41ee5a4dd73093d107bc80df5cebb9a273cc72Ronghua Wu            ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
54665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5467c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
546852e88b2986536e83a7a6da63461556b8734a85f3Ronghua Wu        mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
5469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
5470c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
5471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
547226a48f304a8754d655e554178ffb6d7ba4c5aac3Lajos Molnar    notify = new AMessage(kWhatOMXMessageList, mCodec);
5473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
5474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
547690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.setComponentName(componentName);
5477ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
5478ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5479ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
5480ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
54811713460104b86f6be3a5d9993d9ace864d889b2dChong Zhang        mCodec->mFlags |= kFlagIsGrallocUsageProtected;
54820167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
5483ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
5484ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
5485afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
5486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
5487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
5488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
54895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
54905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5491d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentAllocated);
54925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
54935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
54945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5496c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
5497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
54995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
55005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5501c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
5502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
5504c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
5505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5506c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5507c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
5508c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
5509c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5510f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
5511f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
5512f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5513f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
5514f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
5515054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
5516054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->mMetadataBuffersToSubmit = 0;
5517a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
5518e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
5519e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
55204e865a3cfe4c955e0890321a6b488cf661808b63Lajos Molnar    mCodec->mBaseOutputFormat.clear();
5521054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5522c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
5523c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
5524c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5525c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
5526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
5527c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
5529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
553054b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    mCodec->mExplicitShutdown = false;
5531f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia
5532f393c33e65ae51a7cf168b4e15771b152f996b32Wei Jia    mCodec->processDeferredMessages();
5533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5535c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
5536c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
55370806340688c937e7b78c2d89db3809274130df4eLajos Molnar        (void)mCodec->mOMX->freeNode(mCodec->mNode);
5538c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5539c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
5540c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5541c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
554254b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    if (mCodec->mExplicitShutdown) {
554354b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        sp<AMessage> notify = mCodec->mNotify->dup();
5544d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
554554b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        notify->post();
554654b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar        mCodec->mExplicitShutdown = false;
554754b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar    }
5548c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5549c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5550c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
5551c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
5552c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5553c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
5554c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
5555c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
5557c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5560c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
55617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
55627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
55637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
55647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
55657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
55667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
55677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
55688f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case ACodec::kWhatSetInputSurface:
5569d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        {
55708f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            onSetInputSurface(msg);
5571d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            handled = true;
5572d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            break;
5573d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        }
5574d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5575c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
5576c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5577c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
5578c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5579c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5581c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5582c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
5583c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5584c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
5585c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
5586c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
5587c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
558854b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
5589c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
5590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5591c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5594c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5595c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
5596c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
5597c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5598d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5599c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
5600c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5601c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
5602c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
5603c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
5604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
5606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
5607c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
5608c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
5610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
5611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
56135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
56145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
56155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5616ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    CHECK(mCodec->mNode != 0);
56175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
56180806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = OK;
56195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
56200806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (!msg->findString("mime", &mime)) {
56210806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = BAD_VALUE;
56220806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
56230806340688c937e7b78c2d89db3809274130df4eLajos Molnar        err = mCodec->configureCodec(mime.c_str(), msg);
56240806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
56255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5626c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
5627c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
5628c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
5629251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
5630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
56315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
56345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
5635d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatComponentConfigured);
5636e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
5637e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
56385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
56395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5640c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
5641c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
56425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
56435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5644d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t ACodec::LoadedState::setupInputSurface() {
5645d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = OK;
5646a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5647d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mRepeatFrameDelayUs > 0ll) {
5648a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
5649a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
5650a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
5651a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
5652a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
5653a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
5654a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5655a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
5656a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
5657a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
5658a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
5659a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
5660d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
5661a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
5662a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
5663a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
5664d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxPtsGapUs > 0ll) {
566594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
566694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
566794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
566894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
566994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
567094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
567194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
567294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
567394ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
567472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
567572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
5676d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
56772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
56782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
56792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
5680d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mMaxFps > 0) {
568137b2b389139ed638831e49708c947863eef631efRonghua Wu        err = mCodec->mOMX->setInternalOption(
568237b2b389139ed638831e49708c947863eef631efRonghua Wu                mCodec->mNode,
568337b2b389139ed638831e49708c947863eef631efRonghua Wu                kPortIndexInput,
568437b2b389139ed638831e49708c947863eef631efRonghua Wu                IOMX::INTERNAL_OPTION_MAX_FPS,
568537b2b389139ed638831e49708c947863eef631efRonghua Wu                &mCodec->mMaxFps,
568637b2b389139ed638831e49708c947863eef631efRonghua Wu                sizeof(mCodec->mMaxFps));
568737b2b389139ed638831e49708c947863eef631efRonghua Wu
568837b2b389139ed638831e49708c947863eef631efRonghua Wu        if (err != OK) {
568937b2b389139ed638831e49708c947863eef631efRonghua Wu            ALOGE("[%s] Unable to configure max fps (err %d)",
569037b2b389139ed638831e49708c947863eef631efRonghua Wu                    mCodec->mComponentName.c_str(),
569137b2b389139ed638831e49708c947863eef631efRonghua Wu                    err);
5692d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
569337b2b389139ed638831e49708c947863eef631efRonghua Wu        }
569437b2b389139ed638831e49708c947863eef631efRonghua Wu    }
569537b2b389139ed638831e49708c947863eef631efRonghua Wu
5696d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mTimePerCaptureUs > 0ll
56972c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
56982c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
56992c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
57002c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
57012c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
57022c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
57032c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
57042c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
57052c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
57062c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
57072c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
57082c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
57092c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
57102c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
57112c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
5712d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
57132c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
57142c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
571572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5716d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (mCodec->mCreateInputBuffersSuspended) {
571772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
571872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
571972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
572072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
572172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
572272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
572372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
572472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
572572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
572672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
572794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
572894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
5729d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            return err;
573094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
573194ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
573294ee4b708acfa941581160b267afb79192b1d816Chong Zhang
5733d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return OK;
5734d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5735d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5736d291c222357303b9611cab89d0c3b047584ef377Chong Zhangvoid ACodec::LoadedState::onCreateInputSurface(
5737d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> & /* msg */) {
5738d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    ALOGV("onCreateInputSurface");
5739d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5740d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5741d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
5742d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5743d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
5744d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = mCodec->mOMX->createInputSurface(
5745054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mCodec->mNode, kPortIndexInput, &bufferProducer, &mCodec->mInputMetadataType);
5746d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5747d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5748d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5749d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5750d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
57517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
57527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
57537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
57547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
57557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
57567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
57577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
57587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
57597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
57607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
57617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
57627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
57637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
57647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
57658f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangvoid ACodec::LoadedState::onSetInputSurface(
5766d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<AMessage> &msg) {
57678f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    ALOGV("onSetInputSurface");
5768d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5769d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> notify = mCodec->mNotify->dup();
5770d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->setInt32("what", CodecBase::kWhatInputSurfaceAccepted);
5771d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5772d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<RefBase> obj;
5773d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK(msg->findObject("input-surface", &obj));
5774d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
5775d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
57768f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    status_t err = mCodec->mOMX->setInputSurface(
5777054219874873b41f1c815552987c10465c34ba2bLajos Molnar            mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
5778054219874873b41f1c815552987c10465c34ba2bLajos Molnar            &mCodec->mInputMetadataType);
5779d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5780d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err == OK) {
5781d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        err = setupInputSurface();
5782d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5783d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5784d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
5785d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // Can't use mCodec->signalError() here -- MediaCodec won't forward
5786d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // the error through because it's in the "configured" state.  We
5787d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        // send a kWhatInputSurfaceAccepted with an error value instead.
57888f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        ALOGE("[%s] onSetInputSurface returning error %d",
5789d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->mComponentName.c_str(), err);
5790d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        notify->setInt32("err", err);
5791d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
5792d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    notify->post();
5793d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
5794d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
57965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
57975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57980806340688c937e7b78c2d89db3809274130df4eLajos Molnar    status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
57990806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (err != OK) {
58000806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58010806340688c937e7b78c2d89db3809274130df4eLajos Molnar    } else {
58020806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->changeState(mCodec->mLoadedToIdleState);
58030806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
5804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5808f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
5809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5812f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
58133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
5814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5815cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
5816cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
581729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
5818cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
5819cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
5820cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
5821251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
582291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
582391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
5824cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
5825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5827f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
5828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
5829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
5831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
5832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
5835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5837f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
5838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
583972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
58476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
58486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
58496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
58506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
58516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
58526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
58536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
58546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
58556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
58566463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
58576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
58586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
58596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
58606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
58616463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
5862d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
58636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
58646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
58656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
58666463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
5867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5872f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
5873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
58770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = OK;
58780806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
58790806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
58800806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in LoadedToIdleState: %s(%u) %s(%u)",
58810806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
58820806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
58830806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = FAILED_TRANSACTION;
58840806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58860806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
58870806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = mCodec->mOMX->sendCommand(
58880806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting);
58890806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58910806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
58920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
58930806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
58940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mIdleToExecutingState);
58950806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5907f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
5908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
5909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5911f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
59123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
5913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5915f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
5916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
591772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
5918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
5919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
5920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
5921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5924d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
5925d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5926d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
5927d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5928d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5929d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5930d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
5931d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
5932d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
5933d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
5934d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar            notify->setInt32("what", CodecBase::kWhatFlushCompleted);
5935d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
5936d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
5937d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
5938d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
5939d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
59406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
59416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
59426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
59436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
59446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
59456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
5946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
5948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5951f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
5952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
5953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
5954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
5955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
59560806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
59570806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateExecuting) {
59580806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToExecutingState: %s(%u) %s(%u)",
59590806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
59600806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
59610806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
59620806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
59630806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
5964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
5966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
5967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
5969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
5970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
5972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
5973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
5974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
5977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5978f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
5979349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
5980349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
5981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5983f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
5984ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
5985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
5986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
5987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5988054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
5989054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
5990054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
5991054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
5992054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
5993054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
5994054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
5995054219874873b41f1c815552987c10465c34ba2bLajos Molnar            if (mCodec->submitOutputMetadataBuffer() != OK)
5996054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
5997054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
5998054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
59994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
60004dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6001054219874873b41f1c815552987c10465c34ba2bLajos Molnar    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
6002054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6003054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6004054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
60050806340688c937e7b78c2d89db3809274130df4eLajos Molnar    bool failed = false;
6006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
6007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
6008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
60100806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US
60110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
60120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us or the surface");
60130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
60140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
60150806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
6018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
6019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
60210806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (info->mStatus != BufferInfo::OWNED_BY_US) {
60220806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("buffers should be owned by us");
60230806340688c937e7b78c2d89db3809274130df4eLajos Molnar                failed = true;
60240806340688c937e7b78c2d89db3809274130df4eLajos Molnar                break;
60250806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60280806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
6029349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
603015ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->checkWriteFence("submitRegularOutputBuffers");
603115ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        status_t err = mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID, info->mFenceFd);
603215ab4996019387f27a48b81cb4774c21502bc0e5Lajos Molnar        info->mFenceFd = -1;
60330806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
60340806340688c937e7b78c2d89db3809274130df4eLajos Molnar            failed = true;
60350806340688c937e7b78c2d89db3809274130df4eLajos Molnar            break;
60360806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
6039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
60400806340688c937e7b78c2d89db3809274130df4eLajos Molnar
60410806340688c937e7b78c2d89db3809274130df4eLajos Molnar    if (failed) {
60420806340688c937e7b78c2d89db3809274130df4eLajos Molnar        mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
60430806340688c937e7b78c2d89db3809274130df4eLajos Molnar    }
6044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6046054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
6047c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
6048054219874873b41f1c815552987c10465c34ba2bLajos Molnar    if (mCodec->storingMetadataInDecodedBuffers()) {
6049054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
6050054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
6051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
6052054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6053f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
6054349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
60550806340688c937e7b78c2d89db3809274130df4eLajos Molnar        ALOGV("[%s] We're already active, no need to resume.", mCodec->mComponentName.c_str());
6056349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
6057349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
6058349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
6060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60613cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    // Post all available input buffers
6062777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    if (mCodec->mBuffers[kPortIndexInput].size() == 0u) {
6063777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim        ALOGW("[%s] we don't have any input buffers to resume", mCodec->mComponentName.c_str());
6064777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim    }
6065777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim
60663cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); i++) {
60673cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
60683cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_US) {
60693cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar            postFillThisBuffer(info);
60703cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar        }
60713cb576166020bfdc1522b33919fe5ff8d211d0a3Lajos Molnar    }
6072349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6073349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
6074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6076f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
60773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
6078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
607990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
6080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
6081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6083f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
6084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
6090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
6091c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
6092c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6093c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
609454b0bc74e051bd7df10cd657b481d88db6cdaa27Lajos Molnar            mCodec->mExplicitShutdown = true;
6095c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
6096c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
6097349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6098349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
60990806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(
61000806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle);
61010806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
61020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (keepComponentAllocated) {
61030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
61040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
61050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                // TODO: do some recovery here.
61060806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
61070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mExecutingToIdleState);
61080806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
61167a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
6117ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                 "(codec owns %zu/%zu input, %zu/%zu output).",
6118d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
6119d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
6120d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
6121d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
6122d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
6123d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6124349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
6125349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
61260806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err = mCodec->mOMX->sendCommand(mCodec->mNode, OMX_CommandFlush, OMX_ALL);
61270806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err != OK) {
61280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
61290806340688c937e7b78c2d89db3809274130df4eLajos Molnar            } else {
61300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->changeState(mCodec->mFlushingState);
61310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
6138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
6140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6145496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
6146496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
6147496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
6148496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
6149496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
6150496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
6151496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6152496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
6153496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
6154496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
6155496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
6156a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
6157a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
6158a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
6159a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
6160a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6161a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
6162a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6163a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
6164a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
6165a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
6166a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
6167a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
6168a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6169a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
6170a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
6171a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6172a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
61737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
61747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
61756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
61767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
61777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
61787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
61797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
61804dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
6181054219874873b41f1c815552987c10465c34ba2bLajos Molnar        case kWhatSubmitOutputMetadataBufferIfEOS:
61824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
61834dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
61844dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
6185054219874873b41f1c815552987c10465c34ba2bLajos Molnar                status_t err = mCodec->submitOutputMetadataBuffer();
61864dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
6187054219874873b41f1c815552987c10465c34ba2bLajos Molnar                    mCodec->signalSubmitOutputMetadataBufferIfEOS_workaround();
61884dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
61894dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
61904dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
61914dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
61924dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
6193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6201a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
6202a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
6203530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
6204a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
6205a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
6206a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
6207a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
6208a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6209a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
6210a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
6211a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
6212a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
6213a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
6214a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6215a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
6216a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
6217a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
6218a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
6219a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
6220a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
6221a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
6222a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
622372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
622472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
622572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
622672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
622772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
622872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
622972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
623072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
623172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
623272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
623372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
623472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
623572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
623672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
623772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
623872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6239e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
6240e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
6241e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
6242e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
6243b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
6244b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
6245e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
6246e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
6247e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
6248e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
6249b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
6250b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6251b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
6252b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
6253b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
6254b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
6255b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
6256b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6257b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
6258b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
6259b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
6260b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
6261b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
6262b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
6263b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
6264b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
6265e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
6266e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
62678db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    float rate;
62688db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    if (params->findFloat("operating-rate", &rate) && rate > 0) {
62698db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        status_t err = setOperatingRate(rate, mIsVideo);
62708db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        if (err != OK) {
62718db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            ALOGE("Failed to set parameter 'operating-rate' (err %d)", err);
62728db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu            return err;
62738db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu        }
62748db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu    }
62758db8813d39e3c8b5fbd580dfc3062830744afd63Ronghua Wu
6276a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
6277a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
6278a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
62796507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
62806507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
6281d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar    notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
62826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
62836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
62846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
62856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
62866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
62876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
62886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
62896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
629090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::ExecutingState::onOMXFrameRendered(int64_t mediaTimeUs, nsecs_t systemNano) {
629190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
629290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
629390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
629490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6295f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
6296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
6299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
6301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
6303054219874873b41f1c815552987c10465c34ba2bLajos Molnar                mCodec->mMetadataBuffersToSubmit = 0;
6304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
6305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
6306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
6307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
6308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6309349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
6310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
631231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
631331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
6314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
6315ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08x",
6316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
6317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
6323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6334f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
6335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
6336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6339f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
6340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
6341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
6342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
6343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
6346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
6348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6350f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
6351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6357349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
6358e6eea3a6b6e0cf92287ec1ceb8350f201d17e1acPer Persson        case kWhatSetParameters:
6359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6360349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
63613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
6362349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
6363349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6377f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
63783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
6379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
6380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
638290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarbool ACodec::OutputPortSettingsChangedState::onOMXFrameRendered(
638390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs, nsecs_t systemNano) {
638490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mCodec->onFrameRendered(mediaTimeUs, systemNano);
638590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return true;
638690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
638790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6388f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
6389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
63940806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (data2 != (OMX_U32)kPortIndexOutput) {
63950806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGW("ignoring EventCmdComplete CommandPortDisable for port %u", data2);
63960806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    return false;
63970806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63990806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now disabled.", mCodec->mComponentName.c_str());
6400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64010806340688c937e7b78c2d89db3809274130df4eLajos Molnar                status_t err = OK;
64020806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (!mCodec->mBuffers[kPortIndexOutput].isEmpty()) {
64030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE("disabled port should be empty, but has %zu buffers",
64040806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mBuffers[kPortIndexOutput].size());
64050806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = FAILED_TRANSACTION;
64060806340688c937e7b78c2d89db3809274130df4eLajos Molnar                } else {
64070806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    mCodec->mDealer[kPortIndexOutput].clear();
64080806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
64110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->mOMX->sendCommand(
64120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput);
64130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err == OK) {
64160806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    err = mCodec->allocateBuffersOnPort(kPortIndexOutput);
64170806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    ALOGE_IF(err != OK, "Failed to allocate output port buffers after port "
64180806340688c937e7b78c2d89db3809274130df4eLajos Molnar                            "reconfiguration: (%d)", err);
64190806340688c937e7b78c2d89db3809274130df4eLajos Molnar                }
6420cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
64210806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (err != OK) {
6422251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
6423d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6424755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
6425755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
6426755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
6427755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
6428755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
6429755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
6430755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
6431755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
6432cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
6433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
6436777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (data2 != (OMX_U32)kPortIndexOutput) {
6437777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("ignoring EventCmdComplete OMX_CommandPortEnable for port %u", data2);
6438777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6439777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
644131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
644231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
64430806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGV("[%s] Output port now reenabled.", mCodec->mComponentName.c_str());
6444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6445349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
6446349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
6447349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
6448349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
6450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
6452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
6459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6464f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
64655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
64665778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
6467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
6470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
64770806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGW("Ignoring flush request in ExecutingToIdleState");
6478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6497f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
64983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
649931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
65005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
650131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
6502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6504f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
6505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
65090806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
65100806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateIdle) {
65110806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in ExecutingToIdleState: %s(%u) %s(%u)",
65120806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
65130806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
65140806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
65150806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
65160806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
65195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
6521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6526349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
6527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
6528349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
6529349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6530349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6531349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
65360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
6537f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
65385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
65390806340688c937e7b78c2d89db3809274130df4eLajos Molnar        status_t err = mCodec->mOMX->sendCommand(
65400806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded);
65410806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err == OK) {
65420806340688c937e7b78c2d89db3809274130df4eLajos Molnar            err = mCodec->freeBuffersOnPort(kPortIndexInput);
65430806340688c937e7b78c2d89db3809274130df4eLajos Molnar            status_t err2 = mCodec->freeBuffersOnPort(kPortIndexOutput);
65440806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (err == OK) {
65450806340688c937e7b78c2d89db3809274130df4eLajos Molnar                err = err2;
65460806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
65470806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
6548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
65490167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
65500167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
6551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
6552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
6553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
6554bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
6555b2d0b487efd40700199852c9a18b369b1651f15bLajos Molnar            pushBlankBuffersToNativeWindow(mCodec->mNativeWindow.get());
6556bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
6557bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
65580806340688c937e7b78c2d89db3809274130df4eLajos Molnar        if (err != OK) {
65590806340688c937e7b78c2d89db3809274130df4eLajos Molnar            mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
65600806340688c937e7b78c2d89db3809274130df4eLajos Molnar            return;
65610806340688c937e7b78c2d89db3809274130df4eLajos Molnar        }
65620806340688c937e7b78c2d89db3809274130df4eLajos Molnar
6563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
6564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6567f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
6568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6574f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
6575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
6576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6583f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
6584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6587f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
6588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
6594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
6602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
66030806340688c937e7b78c2d89db3809274130df4eLajos Molnar            ALOGE("Got flush request in IdleToLoadedState");
6604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6615f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
66163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
6617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6619f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
6620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
66240806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandStateSet
66250806340688c937e7b78c2d89db3809274130df4eLajos Molnar                    || data2 != (OMX_U32)OMX_StateLoaded) {
66260806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("Unexpected command completion in IdleToLoadedState: %s(%u) %s(%u)",
66270806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1,
66280806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_STATETYPE)data2), data2);
66290806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
66300806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
66310806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
6634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
6644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6645f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
6646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
6647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6649f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
66503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
6651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
6653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6655f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
6656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
6657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
6659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
6660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
6662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
6666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
6667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
6668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
6669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
6674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
6675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
6678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6680f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
6681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
6682ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    ALOGV("[%s] FlushingState onOMXEvent(%u,%d)",
6683ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar            mCodec->mComponentName.c_str(), event, (OMX_S32)data1);
6684d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
6685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
6686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
6687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
66880806340688c937e7b78c2d89db3809274130df4eLajos Molnar            if (data1 != (OMX_U32)OMX_CommandFlush) {
66890806340688c937e7b78c2d89db3809274130df4eLajos Molnar                ALOGE("unexpected EventCmdComplete %s(%d) data2:%d in FlushingState",
66900806340688c937e7b78c2d89db3809274130df4eLajos Molnar                        asString((OMX_COMMANDTYPE)data1), data1, data2);
66910806340688c937e7b78c2d89db3809274130df4eLajos Molnar                mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
66920806340688c937e7b78c2d89db3809274130df4eLajos Molnar                return true;
66930806340688c937e7b78c2d89db3809274130df4eLajos Molnar            }
6694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
6696777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (mFlushComplete[data2]) {
6697777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("Flush already completed for %s port",
6698777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            data2 == kPortIndexInput ? "input" : "output");
6699777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return true;
6700777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
6702e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
67030806340688c937e7b78c2d89db3809274130df4eLajos Molnar                if (mFlushComplete[kPortIndexInput] && mFlushComplete[kPortIndexOutput]) {
6704e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
6705e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
6706777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else if (data2 == OMX_ALL) {
6707777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                if (!mFlushComplete[kPortIndexInput] || !mFlushComplete[kPortIndexOutput]) {
6708777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    ALOGW("received flush complete event for OMX_ALL before ports have been"
6709777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            "flushed (%d/%d)",
6710777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                            mFlushComplete[kPortIndexInput], mFlushComplete[kPortIndexOutput]);
6711777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                    return false;
6712777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                }
6713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
6715777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim            } else {
6716777cf6d2788b12bbd68f620cda94a128462a208dJinsuk Kim                ALOGW("data2 not OMX_ALL but %u in EventCmdComplete CommandFlush", data2);
6717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
6718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
6720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
6721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6722349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
6723349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
67241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec);
6725349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
6726609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            msg->setInt32("node", mCodec->mNode);
6727349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
6728349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
6729349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
6730349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
67313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
6732349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
6733349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6734349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
6735349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6736349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
6737349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
6738349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
6739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
6740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
6741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
6744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6746f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
6747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
6748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6752f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
6753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
6754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
6756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6758f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
6759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
6760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
6761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
67627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
67637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
67647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
67657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
676690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mCodec->mRenderTracker.clear(systemTime(CLOCK_MONOTONIC));
676790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
6769d8cbe4a024ef54adf043b6ea31fa22271b8b2c51Lajos Molnar        notify->setInt32("what", CodecBase::kWhatFlushCompleted);
6770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
6771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
6773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
6774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6775dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
6776dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
6777f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
6778f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
6779f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
6780f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
6781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
6782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
6783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
6784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
6786